Skip to content

Commit

Permalink
Finish text base credential auth
Browse files Browse the repository at this point in the history
  • Loading branch information
thingnotok committed Nov 2, 2022
1 parent 6018daa commit 5d9b037
Show file tree
Hide file tree
Showing 7 changed files with 129 additions and 27 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ data.json

# Exclude macOS Finder (System Explorer) View States
.DS_Store
.cred.json
.token.json
40 changes: 40 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"dependencies": {
"@google-cloud/local-auth": "^2.1.1",
"googleapis": "^109.0.0",
"open": "^8.4.0",
"turndown": "^7.1.1"
}
}
}
67 changes: 56 additions & 11 deletions src/GOauth.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { Notice } from 'obsidian';
import { google } from 'googleapis';
import { listLabels } from 'src/GmailAPI';
const fs = require('fs').promises;
import { authenticate } from '@google-cloud/local-auth';
import { OAuth2Client } from 'google-auth-library';
const http = require('http');
const url = require('url');
const opn = require('open');
const destroyer = require('server-destroy');

const SCOPES = [
'https://www.googleapis.com/auth/gmail.modify'
Expand All @@ -18,7 +21,7 @@ export async function loadSavedCredentialsIfExist(settings: ObsGMailSettings) {
}

async function saveCredentials(client: any, cred_path: string, token_path: string) {
const content = await fs.readFile(cred_path);
const content = cred_path;
const keys = JSON.parse(content);
const key = keys.installed || keys.web;
const payload = JSON.stringify({
Expand All @@ -28,24 +31,61 @@ async function saveCredentials(client: any, cred_path: string, token_path: strin
refresh_token: client.credentials.refresh_token,
});
// console.log("TOKEN:" + token_path)
const isExist = await this.app.vault.exists(token_path)
if (!isExist)
await this.app.vault.create(token_path, payload);
await this.app.vault.writeJson(token_path, payload)
// await fs.writeFile(token_path, payload);

}

async function my_authenticate(scopes: Array<string>, credentials: string) {
const keys = JSON.parse(credentials).web
console.log(keys)
const oauth2Client = new google.auth.OAuth2(
keys.client_id,
keys.client_secret,
keys.redirect_uris[0]
);
const redirect_uri = keys.redirect_uris[0]
const ListenPort = redirect_uri.split(':')[1]
return new Promise((resolve, reject) => {
// grab the url that will be used for authorization
const authorizeUrl = oauth2Client.generateAuthUrl({
access_type: 'offline',
scope: scopes.join(' '),
});
const server = http
.createServer(async (req: any, res: any) => {
try {
if (req.url.indexOf('/oauth2callback') > -1) {
const qs = new url.URL(req.url, redirect_uri)
.searchParams;
res.end('Authentication successful! \n You can close the page now');
server.destroy();
const { tokens } = await oauth2Client.getToken(qs.get('code'));
oauth2Client.credentials = tokens; // eslint-disable-line require-atomic-updates
resolve(oauth2Client);
}
} catch (e) {
reject(e);
}
})
.listen(ListenPort, () => {
// open the browser to the authorize url to start the workflow
opn(authorizeUrl, { wait: false }).then((cp: any) => cp.unref());
});
destroyer(server);
});
}

// @ts-ignore
async function authorize(setting: ObsGMailSettings) {
let client = await loadSavedCredentialsIfExist(setting);
if (client) {
return client;
}
console.log("Start Auth")
console.log(setting.cred_path)
// @ts-ignore
client = await authenticate({
scopes: SCOPES,
keyfilePath: setting.cred_path,
});
client = await my_authenticate(SCOPES, setting.cred_path)
// @ts-ignore
if (client.credentials) {
await saveCredentials(client, setting.cred_path, setting.token_path);
Expand All @@ -55,12 +95,17 @@ async function authorize(setting: ObsGMailSettings) {

// @ts-ignore
export async function setupGserviceConnection(settings: ObsGMailSettings) {
const cred_path = "/.obsidian/plugins/obsidian-google-mail/.cred.json"
const keys = JSON.parse(settings.cred_path);
const key = keys.installed || keys.web;
await this.app.vault.writeJson(cred_path, key)
console.log('after create')
const gc = settings.gc
gc.authClient = await authorize(settings)
gc.gmail = google.gmail({
version: 'v1',
auth: gc.authClient
})
settings.labels = await listLabels(gc.gmail) || [[]]
settings.labels = await listLabels(settings.mail_account, gc.gmail) || [[]]
new Notice("Finished Login Setting")
}
24 changes: 12 additions & 12 deletions src/GmailAPI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ export function createGmailConnect(client) {
}


export async function listLabels(gmail: gmail_v1.Gmail) {
export async function listLabels(account: string, gmail: gmail_v1.Gmail) {

const res = await gmail.users.labels.list({
userId: 'me'
userId: account
});
const labels = res.data.labels;
if (!labels || labels.length === 0) {
Expand All @@ -39,9 +39,9 @@ async function getLabelIDbyName(name: string, gmail: gmail_v1.Gmail) {
return result_id;
}

async function saveMail(folder: string, gmail: gmail_v1.Gmail, id: string) {
async function saveMail(account: string, folder: string, gmail: gmail_v1.Gmail, id: string) {
const res = await gmail.users.threads.get({
userId: 'me',
userId: account,
id: id,
format: 'full'
});
Expand All @@ -56,18 +56,18 @@ async function saveMail(folder: string, gmail: gmail_v1.Gmail, id: string) {
// await fs.writeFile(TOKEN_PATH, txt);
}

async function fetchMailList(labelID: string, gmail: gmail_v1.Gmail) {
async function fetchMailList(account: string, labelID: string, gmail: gmail_v1.Gmail) {
const res = await gmail.users.threads.list({
userId: 'me',
userId: account,
labelIds: [labelID],
maxResults: 100
});
return res.data.threads;
}

async function updateLabel(from_labelID: string, to_labelID: string, id: string, gmail: gmail_v1.Gmail) {
async function updateLabel(account: string, from_labelID: string, to_labelID: string, id: string, gmail: gmail_v1.Gmail) {
const res = await gmail.users.threads.modify({
userId: 'me',
userId: account,
id: id,
requestBody: {
addLabelIds: [to_labelID],
Expand All @@ -84,17 +84,17 @@ async function mkdirP(path: string) {
}
}

export async function fetchMails(fromID: string, toID: string, base_folder: string, gmail: gmail_v1.Gmail) {
export async function fetchMails(account: string, fromID: string, toID: string, base_folder: string, gmail: gmail_v1.Gmail) {
new Notice('Start Fetch Mail');
await mkdirP(base_folder)
const threads = await fetchMailList(fromID, gmail) || []
const threads = await fetchMailList(account, fromID, gmail) || []
console.log(threads);
for (let i = 0; i < threads.length; i++) {
if (i % 10 == 0)
new Notice(`Fetching Mail ${i} /${threads.length}`);
const id = threads[i].id || ""
await saveMail(base_folder, gmail, id);
await updateLabel(fromID, toID, id, gmail);
await saveMail(account, base_folder, gmail, id);
await updateLabel(account, fromID, toID, id, gmail);
}
new Notice('End Fetch Mail');
}
7 changes: 5 additions & 2 deletions src/GoogleMail.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ interface ObsGMailSettings {
cred_path: string;
token_path: string;
labels: Array<Array<string>>;
mail_account: string;
}

const DEFAULT_SETTINGS: ObsGMailSettings = {
Expand All @@ -44,7 +45,8 @@ const DEFAULT_SETTINGS: ObsGMailSettings = {
mail_folder: "",
cred_path: "",
token_path: "/.obsidian/plugins/obsidian-google-mail/.token.json",
labels: [[]]
labels: [[]],
mail_account: ""
}


Expand All @@ -58,6 +60,7 @@ export default class ObsGMail extends Plugin {
const ribbonIconEl = this.addRibbonIcon('sheets-in-box', 'gmail fetch',
(evt: MouseEvent) => {
fetchMails(
this.settings.mail_account,
this.settings.from_label,
this.settings.to_label,
this.settings.mail_folder,
Expand All @@ -70,7 +73,7 @@ export default class ObsGMail extends Plugin {
id: 'Gmail-Fetch',
name: 'Gmail-Fetch',
callback: () => {
listLabels(this.settings.gc.gmail).then((labels: string[][]) => {
listLabels(this.settings.mail_account, this.settings.gc.gmail).then((labels: string[][]) => {
console.log(labels);
})
}
Expand Down
13 changes: 12 additions & 1 deletion src/setting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export function draw_settingtab(settingTab) {
containerEl.empty();
containerEl.createEl('h2', { text: 'Setup Google OAuth settings' });
new Setting(containerEl)
.setName('Path of Credential File')
.setName('Credential Content')
.setDesc('Absolut Path to credential file, the file can be placed outside of vault. But addtional permission is required. (on macOS)')
.addText(text => text
.setPlaceholder('Enter the path')
Expand All @@ -24,6 +24,17 @@ export function draw_settingtab(settingTab) {
});
});

new Setting(containerEl)
.setName("Gmail Account")
.setDesc('email account to fetch mails')
.addText(text => text
.setPlaceholder('[email protected]')
.setValue(plugin.settings.mail_account)
.onChange(async (value) => {
plugin.settings.mail_account = value;
await plugin.saveSettings();
}));

new Setting(containerEl)
.setName('>> Mail from label')
.setDesc('Labels to fetched from Gmail').addDropdown(
Expand Down

0 comments on commit 5d9b037

Please sign in to comment.