|
1 | | -import { Notice } from 'obsidian'; |
| 1 | +import { Notice } from "obsidian"; |
2 | 2 | //import { google } from 'googleapis'; |
3 | | -import { listLabels, getMailAccount, createGmailConnect } from 'src/GmailAPI'; |
4 | | -import { ObsGMailSettings } from 'src/setting'; |
5 | | -import http from 'http'; |
6 | | -import url from 'url'; |
7 | | -import opn from 'open'; |
8 | | -import destroyer from 'server-destroy'; |
9 | | -import { auth } from 'google-auth-library'; |
10 | | -import { JSONClient } from 'google-auth-library/build/src/auth/googleauth'; |
11 | | -import { OAuth2Client } from 'google-auth-library/build/src/auth/oauth2client'; |
12 | | -import { assertPresent } from './typeHelpers'; |
13 | | -let server_ = http.createServer() |
| 3 | +import { listLabels, getMailAccount, createGmailConnect } from "src/GmailAPI"; |
| 4 | +import { ObsGMailSettings } from "src/setting"; |
| 5 | +import http from "http"; |
| 6 | +import url from "url"; |
| 7 | +import opn from "open"; |
| 8 | +import destroyer from "server-destroy"; |
| 9 | +import { auth } from "google-auth-library"; |
| 10 | +import { JSONClient } from "google-auth-library/build/src/auth/googleauth"; |
| 11 | +import { OAuth2Client } from "google-auth-library/build/src/auth/oauth2client"; |
| 12 | +import { assertPresent } from "./typeHelpers"; |
| 13 | +let server_ = http.createServer(); |
14 | 14 |
|
15 | | -export type Client = JSONClient | OAuth2Client |
| 15 | +export type Client = JSONClient | OAuth2Client; |
16 | 16 |
|
17 | 17 | const SCOPES = [ |
18 | | - 'https://mail.google.com/', |
19 | | - 'https://www.googleapis.com/auth/gmail.modify', |
20 | | - 'https://www.googleapis.com/auth/userinfo.email' |
21 | | -] |
| 18 | + "https://mail.google.com/", |
| 19 | + "https://www.googleapis.com/auth/gmail.modify", |
| 20 | + "https://www.googleapis.com/auth/userinfo.email", |
| 21 | +]; |
22 | 22 | export async function loadSavedCredentialsIfExist(settings: ObsGMailSettings) { |
23 | | - try { |
24 | | - const content = await this.app.vault.readConfigJson(settings.token_path); |
25 | | - return auth.fromJSON(content); |
26 | | - } catch (err) { |
27 | | - return null; |
28 | | - } |
| 23 | + try { |
| 24 | + const content = await this.app.vault.readConfigJson(settings.token_path); |
| 25 | + return auth.fromJSON(content); |
| 26 | + } catch (err) { |
| 27 | + return null; |
| 28 | + } |
29 | 29 | } |
30 | 30 | export async function removeToken(path: string) { |
31 | | - if (await checkToken(path)) { |
32 | | - await this.app.vault.deleteConfigJson(path); |
33 | | - } |
| 31 | + if (await checkToken(path)) { |
| 32 | + await this.app.vault.deleteConfigJson(path); |
| 33 | + } |
34 | 34 | } |
35 | 35 | export async function checkToken(path: string) { |
36 | | - path = '/.obsidian/' + path + '.json'; |
37 | | - if (await this.app.vault.exists(path)) { |
38 | | - return true; |
39 | | - } |
40 | | - return false; |
| 36 | + path = "/.obsidian/" + path + ".json"; |
| 37 | + if (await this.app.vault.exists(path)) { |
| 38 | + return true; |
| 39 | + } |
| 40 | + return false; |
41 | 41 | } |
42 | 42 |
|
43 | | -async function saveCredentials(client : Client, credentials: string, token_path: string) { |
44 | | - const keys = JSON.parse(credentials); |
45 | | - const key = keys.installed || keys.web; |
46 | | - const payload = { |
47 | | - type: 'authorized_user', |
48 | | - client_id: key.client_id, |
49 | | - client_secret: key.client_secret, |
50 | | - refresh_token: client.credentials.refresh_token |
51 | | - }; |
52 | | - await this.app.vault.writeConfigJson(token_path, payload) |
| 43 | +async function saveCredentials( |
| 44 | + client: Client, |
| 45 | + credentials: string, |
| 46 | + token_path: string, |
| 47 | +) { |
| 48 | + const keys = JSON.parse(credentials); |
| 49 | + const key = keys.installed || keys.web; |
| 50 | + const payload = { |
| 51 | + type: "authorized_user", |
| 52 | + client_id: key.client_id, |
| 53 | + client_secret: key.client_secret, |
| 54 | + refresh_token: client.credentials.refresh_token, |
| 55 | + }; |
| 56 | + await this.app.vault.writeConfigJson(token_path, payload); |
53 | 57 | } |
54 | 58 |
|
55 | 59 | function getPortFromURI(uri: string): number { |
56 | | - const mat = uri.match(/:(?<port>[0-9]+)/m) || [] |
57 | | - return Number(mat[1]) |
| 60 | + const mat = uri.match(/:(?<port>[0-9]+)/m) || []; |
| 61 | + return Number(mat[1]); |
58 | 62 | } |
59 | 63 |
|
60 | | -async function my_authenticate(scopes: Array<string>, credentials: string) : Promise<OAuth2Client> { |
61 | | - const keys = JSON.parse(credentials).web |
62 | | - const oauth2Client = new OAuth2Client( |
63 | | - keys.client_id, |
64 | | - keys.client_secret, |
65 | | - keys.redirect_uris[0] |
66 | | - ); |
67 | | - const redirect_uri = keys.redirect_uris[0] |
68 | | - const ListenPort = getPortFromURI(redirect_uri) |
69 | | - return new Promise((resolve, reject) => { |
70 | | - // grab the url that will be used for authorization |
71 | | - const authorizeUrl = oauth2Client.generateAuthUrl({ |
72 | | - access_type: 'offline', |
73 | | - scope: scopes.join(' '), |
74 | | - prompt: "consent" |
75 | | - }); |
76 | | - if (server_.listening) { |
77 | | - console.log("Server is listening on port, Destroy before create") |
78 | | - server_.destroy(); |
79 | | - } |
80 | | - server_ = http |
81 | | - .createServer(async (req, res) => { |
82 | | - try { |
83 | | - if (req.url && req.url.indexOf('/oauth2callback') > -1) { |
84 | | - const qs = new url.URL(req.url, redirect_uri) |
85 | | - .searchParams; |
86 | | - res.end("Authorization successed. You can close this window."); |
87 | | - server_.destroy(); |
88 | | - const code = qs.get('code'); |
89 | | - assertPresent(code, "Could not get token code"); |
90 | | - const { tokens } = await oauth2Client.getToken(code); |
91 | | - oauth2Client.credentials = tokens; // eslint-disable-line require-atomic-updates |
92 | | - resolve(oauth2Client); |
93 | | - } |
94 | | - } catch (e) { |
95 | | - reject(e); |
96 | | - } |
97 | | - }); |
| 64 | +async function my_authenticate( |
| 65 | + scopes: Array<string>, |
| 66 | + credentials: string, |
| 67 | +): Promise<OAuth2Client> { |
| 68 | + const keys = JSON.parse(credentials).web; |
| 69 | + const oauth2Client = new OAuth2Client( |
| 70 | + keys.client_id, |
| 71 | + keys.client_secret, |
| 72 | + keys.redirect_uris[0], |
| 73 | + ); |
| 74 | + const redirect_uri = keys.redirect_uris[0]; |
| 75 | + const ListenPort = getPortFromURI(redirect_uri); |
| 76 | + return new Promise((resolve, reject) => { |
| 77 | + // grab the url that will be used for authorization |
| 78 | + const authorizeUrl = oauth2Client.generateAuthUrl({ |
| 79 | + access_type: "offline", |
| 80 | + scope: scopes.join(" "), |
| 81 | + prompt: "consent", |
| 82 | + }); |
| 83 | + if (server_.listening) { |
| 84 | + console.log("Server is listening on port, Destroy before create"); |
| 85 | + server_.destroy(); |
| 86 | + } |
| 87 | + server_ = http.createServer(async (req, res) => { |
| 88 | + try { |
| 89 | + if (req.url && req.url.indexOf("/oauth2callback") > -1) { |
| 90 | + const qs = new url.URL(req.url, redirect_uri).searchParams; |
| 91 | + res.end("Authorization successed. You can close this window."); |
| 92 | + server_.destroy(); |
| 93 | + const code = qs.get("code"); |
| 94 | + assertPresent(code, "Could not get token code"); |
| 95 | + const { tokens } = await oauth2Client.getToken(code); |
| 96 | + oauth2Client.credentials = tokens; // eslint-disable-line require-atomic-updates |
| 97 | + resolve(oauth2Client); |
| 98 | + } |
| 99 | + } catch (e) { |
| 100 | + reject(e); |
| 101 | + } |
| 102 | + }); |
98 | 103 |
|
99 | | - server_.listen(ListenPort, () => { |
100 | | - // open the browser to the authorize url to start the workflow |
101 | | - opn(authorizeUrl, { wait: false }).then((cp) => cp.unref()); |
102 | | - }); |
103 | | - destroyer(server_); |
104 | | - }); |
| 104 | + server_.listen(ListenPort, () => { |
| 105 | + // open the browser to the authorize url to start the workflow |
| 106 | + opn(authorizeUrl, { wait: false }).then((cp) => cp.unref()); |
| 107 | + }); |
| 108 | + destroyer(server_); |
| 109 | + }); |
105 | 110 | } |
106 | 111 |
|
107 | 112 | export async function authorize(setting: ObsGMailSettings) { |
108 | | - let client : Client | null = await loadSavedCredentialsIfExist(setting); |
109 | | - if (!client) { |
110 | | - // @ts-ignore |
111 | | - client = await my_authenticate(SCOPES, setting.credentials) |
112 | | - if (server_.listening) |
113 | | - server_.destroy(); |
114 | | - } |
115 | | - // @ts-ignore |
116 | | - if (client.credentials) { |
117 | | - await saveCredentials(client, setting.credentials, setting.token_path); |
118 | | - setting.gc.authClient = client |
119 | | - setting.gc.gmail = createGmailConnect(client); |
120 | | - setting.gc.login = true; |
121 | | - } |
122 | | - else { |
123 | | - new Notice('GMail: Login Failed') |
124 | | - } |
| 113 | + let client: Client | null = await loadSavedCredentialsIfExist(setting); |
| 114 | + if (!client) { |
| 115 | + // @ts-ignore |
| 116 | + client = await my_authenticate(SCOPES, setting.credentials); |
| 117 | + if (server_.listening) server_.destroy(); |
| 118 | + } |
| 119 | + // @ts-ignore |
| 120 | + if (client.credentials) { |
| 121 | + await saveCredentials(client, setting.credentials, setting.token_path); |
| 122 | + setting.gc.authClient = client; |
| 123 | + setting.gc.gmail = createGmailConnect(client); |
| 124 | + setting.gc.login = true; |
| 125 | + } else { |
| 126 | + new Notice("GMail: Login Failed"); |
| 127 | + } |
125 | 128 | } |
126 | 129 |
|
127 | | -function tryRestore(setting: ObsGMailSettings){ |
128 | | - const prev_from = setting.prev_labels.from |
129 | | - const prev_to = setting.prev_labels.to |
130 | | - setting.labels.forEach(nlabel => { |
131 | | - if(prev_from == nlabel[1]) |
132 | | - setting.from_label = prev_from |
133 | | - if(prev_to == nlabel[1]) |
134 | | - setting.to_label = prev_to |
135 | | - }) |
| 130 | +function tryRestore(setting: ObsGMailSettings) { |
| 131 | + const prev_from = setting.prev_labels.from; |
| 132 | + const prev_to = setting.prev_labels.to; |
| 133 | + setting.labels.forEach((nlabel) => { |
| 134 | + if (prev_from == nlabel[1]) setting.from_label = prev_from; |
| 135 | + if (prev_to == nlabel[1]) setting.to_label = prev_to; |
| 136 | + }); |
136 | 137 | } |
137 | 138 |
|
138 | 139 | // @ts-ignore |
139 | 140 | export async function setupGserviceConnection(settings: ObsGMailSettings) { |
140 | | - // console.log(settings) |
141 | | - const gc = settings.gc |
142 | | - await authorize(settings); |
143 | | - // gc.authClient = await authorize(settings) |
144 | | - // gc.gmail = google.gmail({ |
145 | | - // version: 'v1', |
146 | | - // auth: gc.authClient |
147 | | - // }) |
148 | | - if (settings.gc.login) { |
149 | | - assertPresent(gc.gmail, "Gmail is not setup properly") |
150 | | - settings.mail_account = await getMailAccount(gc.gmail); |
151 | | - settings.labels = await listLabels(settings.mail_account, gc.gmail) || [[]]; |
152 | | - tryRestore(settings); |
153 | | - return true; |
154 | | - } |
155 | | - else |
156 | | - return false; |
| 141 | + // console.log(settings) |
| 142 | + const gc = settings.gc; |
| 143 | + await authorize(settings); |
| 144 | + // gc.authClient = await authorize(settings) |
| 145 | + // gc.gmail = google.gmail({ |
| 146 | + // version: 'v1', |
| 147 | + // auth: gc.authClient |
| 148 | + // }) |
| 149 | + if (settings.gc.login) { |
| 150 | + assertPresent(gc.gmail, "Gmail is not setup properly"); |
| 151 | + settings.mail_account = await getMailAccount(gc.gmail); |
| 152 | + settings.labels = (await listLabels(settings.mail_account, gc.gmail)) || [ |
| 153 | + [], |
| 154 | + ]; |
| 155 | + tryRestore(settings); |
| 156 | + return true; |
| 157 | + } else return false; |
157 | 158 | } |
0 commit comments