fluxmail 0.9.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/accounts/googleAuth.d.ts +4 -2
- package/dist/accounts/googleAuth.d.ts.map +1 -1
- package/dist/accounts/googleAuth.js +20 -85
- package/dist/accounts/googleAuth.js.map +1 -1
- package/dist/accounts/microsoftAuth.d.ts +2 -1
- package/dist/accounts/microsoftAuth.d.ts.map +1 -1
- package/dist/accounts/microsoftAuth.js +16 -80
- package/dist/accounts/microsoftAuth.js.map +1 -1
- package/dist/accounts/oauthCallback.d.ts +52 -0
- package/dist/accounts/oauthCallback.d.ts.map +1 -0
- package/dist/accounts/oauthCallback.js +237 -0
- package/dist/accounts/oauthCallback.js.map +1 -0
- package/dist/accounts/registry.d.ts.map +1 -1
- package/dist/accounts/registry.js +12 -5
- package/dist/accounts/registry.js.map +1 -1
- package/dist/accounts/telemetry.d.ts +6 -0
- package/dist/accounts/telemetry.d.ts.map +1 -1
- package/dist/accounts/telemetry.js +19 -0
- package/dist/accounts/telemetry.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +114 -36
- package/dist/cli.js.map +1 -1
- package/dist/cliInstances.d.ts +5 -2
- package/dist/cliInstances.d.ts.map +1 -1
- package/dist/cliInstances.js +74 -22
- package/dist/cliInstances.js.map +1 -1
- package/dist/cliMail.d.ts +2 -0
- package/dist/cliMail.d.ts.map +1 -1
- package/dist/cliMail.js +113 -19
- package/dist/cliMail.js.map +1 -1
- package/dist/cliOutput.d.ts +9 -0
- package/dist/cliOutput.d.ts.map +1 -0
- package/dist/cliOutput.js +76 -0
- package/dist/cliOutput.js.map +1 -0
- package/dist/context.js +1 -1
- package/dist/context.js.map +1 -1
- package/dist/http/admin.d.ts.map +1 -1
- package/dist/http/admin.js +2 -0
- package/dist/http/admin.js.map +1 -1
- package/dist/http/app.d.ts.map +1 -1
- package/dist/http/app.js +4 -0
- package/dist/http/app.js.map +1 -1
- package/dist/http/identity.d.ts.map +1 -1
- package/dist/http/identity.js +2 -0
- package/dist/http/identity.js.map +1 -1
- package/dist/http/rest.d.ts.map +1 -1
- package/dist/http/rest.js +270 -48
- package/dist/http/rest.js.map +1 -1
- package/dist/licensing/entitlements.d.ts +23 -5
- package/dist/licensing/entitlements.d.ts.map +1 -1
- package/dist/licensing/entitlements.js +101 -22
- package/dist/licensing/entitlements.js.map +1 -1
- package/dist/licensing/lease.d.ts +1 -1
- package/dist/licensing/lease.d.ts.map +1 -1
- package/dist/licensing/refresher.d.ts.map +1 -1
- package/dist/licensing/refresher.js +5 -2
- package/dist/licensing/refresher.js.map +1 -1
- package/dist/mcp/buildServer.d.ts.map +1 -1
- package/dist/mcp/buildServer.js +236 -78
- package/dist/mcp/buildServer.js.map +1 -1
- package/dist/mcp/outputSchemas.d.ts +2923 -0
- package/dist/mcp/outputSchemas.d.ts.map +1 -0
- package/dist/mcp/outputSchemas.js +108 -0
- package/dist/mcp/outputSchemas.js.map +1 -0
- package/dist/scheduler/sendScheduler.d.ts +2 -0
- package/dist/scheduler/sendScheduler.d.ts.map +1 -1
- package/dist/scheduler/sendScheduler.js +13 -3
- package/dist/scheduler/sendScheduler.js.map +1 -1
- package/dist/service/deliveryCoordinator.d.ts +45 -0
- package/dist/service/deliveryCoordinator.d.ts.map +1 -0
- package/dist/service/deliveryCoordinator.js +296 -0
- package/dist/service/deliveryCoordinator.js.map +1 -0
- package/dist/service/emailService.d.ts +48 -5
- package/dist/service/emailService.d.ts.map +1 -1
- package/dist/service/emailService.js +258 -37
- package/dist/service/emailService.js.map +1 -1
- package/dist/service/publicErrors.d.ts +12 -0
- package/dist/service/publicErrors.d.ts.map +1 -0
- package/dist/service/publicErrors.js +41 -0
- package/dist/service/publicErrors.js.map +1 -0
- package/dist/service/searchCursor.d.ts +2 -0
- package/dist/service/searchCursor.d.ts.map +1 -1
- package/dist/service/searchCursor.js +6 -2
- package/dist/service/searchCursor.js.map +1 -1
- package/dist/storage/db.d.ts +252 -2
- package/dist/storage/db.d.ts.map +1 -1
- package/dist/storage/db.js +57 -1
- package/dist/storage/db.js.map +1 -1
- package/dist/storage/members.d.ts.map +1 -1
- package/dist/storage/members.js +3 -1
- package/dist/storage/members.js.map +1 -1
- package/dist/storage/restIdempotency.d.ts +6 -0
- package/dist/storage/restIdempotency.d.ts.map +1 -1
- package/dist/storage/restIdempotency.js +8 -0
- package/dist/storage/restIdempotency.js.map +1 -1
- package/dist/storage/scheduledSends.d.ts +2 -1
- package/dist/storage/scheduledSends.d.ts.map +1 -1
- package/dist/storage/scheduledSends.js +6 -0
- package/dist/storage/scheduledSends.js.map +1 -1
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -31,4 +31,4 @@ Fluxmail supports stdio for local MCP clients. Its HTTP server provides Streamab
|
|
|
31
31
|
|
|
32
32
|
## License
|
|
33
33
|
|
|
34
|
-
Fluxmail is source available under the [Elastic License 2.0](https://github.com/churichard/fluxmail/blob/main/LICENSE.md). You may use, modify, create derivative works, and redistribute it subject to that license. The Personal plan supports three mailboxes and one member without a paid key. Official Pro and
|
|
34
|
+
Fluxmail is source available under the [Elastic License 2.0](https://github.com/churichard/fluxmail/blob/main/LICENSE.md). You may use, modify, create derivative works, and redistribute it subject to that license. The Personal plan supports three mailboxes and one member without a paid key. Official Pro, Business, and Enterprise entitlements require a valid Fluxmail license key.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { OAuth2Client, type Credentials } from 'google-auth-library';
|
|
2
2
|
import type { FluxmailConfig } from '../config.js';
|
|
3
3
|
import type { StoredGoogleOAuthApp } from '../instanceConfig.js';
|
|
4
|
+
import { type LoopbackFlowOptions, type OAuthAuthUrlContext } from './oauthCallback.js';
|
|
4
5
|
/**
|
|
5
6
|
* The built-in app uses Fluxmail's approved Gmail permission. Google lists
|
|
6
7
|
* gmail.modify as an allowed scope for users.settings.sendAs.list:
|
|
@@ -36,7 +37,8 @@ export interface AuthorizedOAuthResult extends OAuthResult {
|
|
|
36
37
|
export declare function exchangeCode(client: OAuth2Client, code: string, codeVerifier?: string): Promise<OAuthResult>;
|
|
37
38
|
/**
|
|
38
39
|
* Loopback OAuth flow for the CLI: listens once on config.oauthPort, prints the
|
|
39
|
-
* consent URL, and resolves when Google redirects back with a code
|
|
40
|
+
* consent URL, and resolves when Google redirects back with a code or when the
|
|
41
|
+
* user pastes the callback URL into the terminal.
|
|
40
42
|
*/
|
|
41
|
-
export declare function runLoopbackFlow<T = AuthorizedOAuthResult>(config: FluxmailConfig, onAuthUrl: (url: string) => void, onAuthorized?: (result: AuthorizedOAuthResult) => T | Promise<T
|
|
43
|
+
export declare function runLoopbackFlow<T = AuthorizedOAuthResult>(config: FluxmailConfig, onAuthUrl: (url: string, context: OAuthAuthUrlContext) => void, onAuthorized?: (result: AuthorizedOAuthResult) => T | Promise<T>, options?: LoopbackFlowOptions): Promise<T>;
|
|
42
44
|
//# sourceMappingURL=googleAuth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"googleAuth.d.ts","sourceRoot":"","sources":["../../src/accounts/googleAuth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"googleAuth.d.ts","sourceRoot":"","sources":["../../src/accounts/googleAuth.ts"],"names":[],"mappings":"AACA,OAAO,EAAuB,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAG1F,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAEjE,OAAO,EAAwB,KAAK,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAI9G;;;;GAIG;AACH,eAAO,MAAM,YAAY,UAA8E,CAAC;AAExG,iFAAiF;AACjF,eAAO,MAAM,mBAAmB,UAA0D,CAAC;AAE3F,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAQtG;AAED,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,cAAc,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAc5G;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,cAAc,EACtB,WAAW,EAAE,MAAM,EACnB,WAAW,GAAE,oBAAkD,GAC9D,YAAY,CAGd;AAED,wBAAgB,WAAW,CACzB,MAAM,EAAE,cAAc,EACtB,WAAW,GAAE,oBAAkD,GAC9D,MAAM,EAAE,CAEV;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,CAQlH;AAED,+EAA+E;AAC/E,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,YAAY,EACpB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAYlD;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,qBAAsB,SAAQ,WAAW;IACxD,WAAW,EAAE,oBAAoB,CAAC;CACnC;AAkBD,wBAAsB,YAAY,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAelH;AAED;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,CAAC,GAAG,qBAAqB,EAC7D,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,KAAK,IAAI,EAC9D,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,qBAAqB,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAChE,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,CAAC,CAAC,CAsBZ"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { createServer } from 'node:http';
|
|
2
1
|
import { randomBytes } from 'node:crypto';
|
|
3
2
|
import { CodeChallengeMethod, OAuth2Client } from 'google-auth-library';
|
|
4
3
|
import { EmailError } from '@fluxmail/core';
|
|
4
|
+
import { googleTransporterOptions } from '@fluxmail/provider-gmail';
|
|
5
5
|
import { DEFAULT_GOOGLE_CLIENT_ID } from './defaultGoogleOAuth.js';
|
|
6
|
+
import { runOAuthCallbackFlow } from './oauthCallback.js';
|
|
6
7
|
const GOOGLE_IDENTITY_SCOPES = ['openid', 'email', 'profile'];
|
|
7
8
|
/**
|
|
8
9
|
* The built-in app uses Fluxmail's approved Gmail permission. Google lists
|
|
@@ -32,7 +33,7 @@ export function requireHostedGoogleConfig(config) {
|
|
|
32
33
|
}
|
|
33
34
|
export function createOAuthClient(config, redirectUri, oauthClient = requireGoogleConfig(config)) {
|
|
34
35
|
const { clientId, clientSecret } = oauthClient;
|
|
35
|
-
return new OAuth2Client({ clientId, clientSecret, redirectUri });
|
|
36
|
+
return new OAuth2Client({ clientId, clientSecret, redirectUri, transporterOptions: googleTransporterOptions() });
|
|
36
37
|
}
|
|
37
38
|
export function gmailScopes(config, oauthClient = requireGoogleConfig(config)) {
|
|
38
39
|
return oauthClient.clientId === DEFAULT_GOOGLE_CLIENT_ID ? GMAIL_SCOPES : CUSTOM_GMAIL_SCOPES;
|
|
@@ -78,32 +79,6 @@ function googleTokenError(err) {
|
|
|
78
79
|
const detail = description ?? code ?? oauthErrorText(err instanceof Error ? err.message : undefined) ?? 'unknown error';
|
|
79
80
|
return new EmailError('provider_unavailable', `Google OAuth token exchange failed: ${detail}`);
|
|
80
81
|
}
|
|
81
|
-
function oauthListenerError(err, port) {
|
|
82
|
-
const code = err.code;
|
|
83
|
-
if (code !== 'EADDRINUSE')
|
|
84
|
-
return err;
|
|
85
|
-
return new Error(`OAuth callback port ${port} is already in use.\n\n` +
|
|
86
|
-
'If Fluxmail is already running with Docker Compose, connect the account inside the container:\n\n' +
|
|
87
|
-
' docker compose exec fluxmail fluxmail accounts add gmail\n\n' +
|
|
88
|
-
`Otherwise, stop the process using port ${port} and try again.`, { cause: err });
|
|
89
|
-
}
|
|
90
|
-
function escapeHtml(value) {
|
|
91
|
-
return value.replace(/[&<>"']/g, (char) => {
|
|
92
|
-
const entities = {
|
|
93
|
-
'&': '&',
|
|
94
|
-
'<': '<',
|
|
95
|
-
'>': '>',
|
|
96
|
-
'"': '"',
|
|
97
|
-
"'": ''',
|
|
98
|
-
};
|
|
99
|
-
return entities[char];
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
function callbackPage(title, message) {
|
|
103
|
-
return ('<html><body style="font-family: sans-serif">' +
|
|
104
|
-
`<h2>${escapeHtml(title)}</h2><p>${escapeHtml(message)}</p>` +
|
|
105
|
-
'<p>You can close this tab and return to the terminal.</p></body></html>');
|
|
106
|
-
}
|
|
107
82
|
export async function exchangeCode(client, code, codeVerifier) {
|
|
108
83
|
let tokens;
|
|
109
84
|
try {
|
|
@@ -120,69 +95,29 @@ export async function exchangeCode(client, code, codeVerifier) {
|
|
|
120
95
|
}
|
|
121
96
|
/**
|
|
122
97
|
* Loopback OAuth flow for the CLI: listens once on config.oauthPort, prints the
|
|
123
|
-
* consent URL, and resolves when Google redirects back with a code
|
|
98
|
+
* consent URL, and resolves when Google redirects back with a code or when the
|
|
99
|
+
* user pastes the callback URL into the terminal.
|
|
124
100
|
*/
|
|
125
|
-
export async function runLoopbackFlow(config, onAuthUrl, onAuthorized) {
|
|
101
|
+
export async function runLoopbackFlow(config, onAuthUrl, onAuthorized, options) {
|
|
126
102
|
const oauthClient = { ...requireGoogleConfig(config) };
|
|
127
103
|
const redirectUri = `http://127.0.0.1:${config.oauthPort}/oauth/callback`;
|
|
128
104
|
const client = createOAuthClient(config, redirectUri, oauthClient);
|
|
129
105
|
const { codeVerifier, codeChallenge } = await client.generateCodeVerifierAsync();
|
|
130
106
|
const state = randomBytes(16).toString('hex');
|
|
131
|
-
return
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if (url.pathname !== '/oauth/callback') {
|
|
146
|
-
res.writeHead(404).end('Not found');
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
if (url.searchParams.get('state') !== state) {
|
|
150
|
-
res.writeHead(400).end('State mismatch. Restart the flow.');
|
|
151
|
-
return;
|
|
152
|
-
}
|
|
153
|
-
const error = url.searchParams.get('error');
|
|
154
|
-
if (error) {
|
|
155
|
-
finish(() => reject(new EmailError('invalid_request', `Google OAuth error: ${error}`)));
|
|
156
|
-
res.writeHead(400).end(`Google returned an error: ${error}. You can close this tab.`);
|
|
157
|
-
return;
|
|
158
|
-
}
|
|
159
|
-
const code = url.searchParams.get('code');
|
|
160
|
-
if (!code) {
|
|
161
|
-
res.writeHead(400).end('Missing code parameter.');
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
const result = { ...(await exchangeCode(client, code, codeVerifier)), oauthClient };
|
|
165
|
-
const accepted = onAuthorized ? await onAuthorized(result) : result;
|
|
166
|
-
finish(() => resolve(accepted));
|
|
167
|
-
res
|
|
168
|
-
.writeHead(200, { 'content-type': 'text/html; charset=utf-8' })
|
|
169
|
-
.end(callbackPage(`${result.email} is connected to Fluxmail`, 'The account is ready to use.'));
|
|
170
|
-
}
|
|
171
|
-
catch (err) {
|
|
172
|
-
finish(() => reject(err));
|
|
173
|
-
const expected = err instanceof EmailError;
|
|
174
|
-
const message = expected
|
|
175
|
-
? err.message
|
|
176
|
-
: 'Fluxmail could not finish connecting this account. Check the terminal for details.';
|
|
177
|
-
res
|
|
178
|
-
.writeHead(expected ? 400 : 500, { 'content-type': 'text/html; charset=utf-8' })
|
|
179
|
-
.end(callbackPage('Fluxmail could not connect this account', message));
|
|
180
|
-
}
|
|
181
|
-
});
|
|
182
|
-
server.on('error', (err) => reject(oauthListenerError(err, config.oauthPort)));
|
|
183
|
-
server.listen(config.oauthPort, config.oauthHost, () => {
|
|
184
|
-
onAuthUrl(buildAuthUrl(client, state, gmailScopes(config, oauthClient), codeChallenge));
|
|
185
|
-
});
|
|
107
|
+
return runOAuthCallbackFlow({
|
|
108
|
+
provider: 'gmail',
|
|
109
|
+
redirectUri,
|
|
110
|
+
host: config.oauthHost,
|
|
111
|
+
port: config.oauthPort,
|
|
112
|
+
state,
|
|
113
|
+
authUrl: buildAuthUrl(client, state, gmailScopes(config, oauthClient), codeChallenge),
|
|
114
|
+
onAuthUrl,
|
|
115
|
+
complete: async (code) => {
|
|
116
|
+
const result = { ...(await exchangeCode(client, code, codeVerifier)), oauthClient };
|
|
117
|
+
const value = onAuthorized ? await onAuthorized(result) : result;
|
|
118
|
+
return { email: result.email, value };
|
|
119
|
+
},
|
|
120
|
+
options,
|
|
186
121
|
});
|
|
187
122
|
}
|
|
188
123
|
//# sourceMappingURL=googleAuth.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"googleAuth.js","sourceRoot":"","sources":["../../src/accounts/googleAuth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"googleAuth.js","sourceRoot":"","sources":["../../src/accounts/googleAuth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { FluxmailConfig } from '../config.js';
|
|
2
2
|
import type { StoredMicrosoftOAuthApp } from '../instanceConfig.js';
|
|
3
|
+
import { type LoopbackFlowOptions, type OAuthAuthUrlContext } from './oauthCallback.js';
|
|
3
4
|
export declare const MICROSOFT_SCOPES: string[];
|
|
4
5
|
export interface MicrosoftCredentials {
|
|
5
6
|
accessToken: string;
|
|
@@ -21,5 +22,5 @@ export declare function requireHostedMicrosoftConfig(config: FluxmailConfig): No
|
|
|
21
22
|
export declare function buildMicrosoftAuthUrl(config: FluxmailConfig, redirectUri: string, state: string, verifier: string, oauthClient?: StoredMicrosoftOAuthApp): string;
|
|
22
23
|
export declare function refreshMicrosoftCredentials(config: FluxmailConfig, credentials: MicrosoftCredentials): Promise<MicrosoftCredentials>;
|
|
23
24
|
export declare function exchangeMicrosoftCode(config: FluxmailConfig, code: string, redirectUri: string, verifier: string, clientAuth?: 'public' | 'confidential', oauthClient?: StoredMicrosoftOAuthApp): Promise<MicrosoftOAuthResult>;
|
|
24
|
-
export declare function runMicrosoftLoopbackFlow<T = MicrosoftOAuthResult>(config: FluxmailConfig, onAuthUrl: (url: string) => void, onAuthorized?: (result: MicrosoftOAuthResult) => T | Promise<T
|
|
25
|
+
export declare function runMicrosoftLoopbackFlow<T = MicrosoftOAuthResult>(config: FluxmailConfig, onAuthUrl: (url: string, context: OAuthAuthUrlContext) => void, onAuthorized?: (result: MicrosoftOAuthResult) => T | Promise<T>, options?: LoopbackFlowOptions): Promise<T>;
|
|
25
26
|
//# sourceMappingURL=microsoftAuth.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"microsoftAuth.d.ts","sourceRoot":"","sources":["../../src/accounts/microsoftAuth.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"microsoftAuth.d.ts","sourceRoot":"","sources":["../../src/accounts/microsoftAuth.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AACpE,OAAO,EAAwB,KAAK,mBAAmB,EAAE,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAE9G,eAAO,MAAM,gBAAgB,UAS5B,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,oFAAoF;IACpF,UAAU,CAAC,EAAE,QAAQ,GAAG,cAAc,CAAC;IACvC,uDAAuD;IACvD,mBAAmB,CAAC,EAAE,uBAAuB,CAAC;CAC/C;AAWD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,oBAAoB,CAAC;CACnC;AAED,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAQvG;AAED,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,cAAc,GAAG,WAAW,CAAC,cAAc,CAAC,WAAW,CAAC,CAAC,CAc7G;AAUD,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,cAAc,EACtB,WAAW,EAAE,MAAM,EACnB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,MAAM,EAChB,WAAW,GAAE,uBAAwD,GACpE,MAAM,CAeR;AAqDD,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,cAAc,EACtB,WAAW,EAAE,oBAAoB,GAChC,OAAO,CAAC,oBAAoB,CAAC,CAc/B;AA+CD,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,cAAc,EACtB,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,UAAU,GAAE,QAAQ,GAAG,cAAyB,EAChD,WAAW,GAAE,uBAAwD,GACpE,OAAO,CAAC,oBAAoB,CAAC,CAiB/B;AAED,wBAAsB,wBAAwB,CAAC,CAAC,GAAG,oBAAoB,EACrE,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,KAAK,IAAI,EAC9D,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,oBAAoB,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAC/D,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,CAAC,CAAC,CAqBZ"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createHash, randomBytes } from 'node:crypto';
|
|
2
|
-
import { createServer } from 'node:http';
|
|
3
2
|
import { EmailError } from '@fluxmail/core';
|
|
3
|
+
import { runOAuthCallbackFlow } from './oauthCallback.js';
|
|
4
4
|
export const MICROSOFT_SCOPES = [
|
|
5
5
|
'openid',
|
|
6
6
|
'profile',
|
|
@@ -147,89 +147,25 @@ export async function exchangeMicrosoftCode(config, code, redirectUri, verifier,
|
|
|
147
147
|
await verifyMicrosoftMailbox(credentials.accessToken);
|
|
148
148
|
return { ...identity, credentials };
|
|
149
149
|
}
|
|
150
|
-
function
|
|
151
|
-
return value.replace(/[&<>"']/g, (char) => {
|
|
152
|
-
const entities = {
|
|
153
|
-
'&': '&',
|
|
154
|
-
'<': '<',
|
|
155
|
-
'>': '>',
|
|
156
|
-
'"': '"',
|
|
157
|
-
"'": ''',
|
|
158
|
-
};
|
|
159
|
-
return entities[char];
|
|
160
|
-
});
|
|
161
|
-
}
|
|
162
|
-
function callbackPage(title, message) {
|
|
163
|
-
return ('<html><body style="font-family: sans-serif">' +
|
|
164
|
-
`<h2>${escapeHtml(title)}</h2><p>${escapeHtml(message)}</p>` +
|
|
165
|
-
'<p>You can close this tab and return to the terminal.</p></body></html>');
|
|
166
|
-
}
|
|
167
|
-
function listenerError(error, port) {
|
|
168
|
-
if (error.code !== 'EADDRINUSE')
|
|
169
|
-
return error;
|
|
170
|
-
return new Error(`OAuth callback port ${port} is already in use.\n\n` +
|
|
171
|
-
'If Fluxmail is running with Docker Compose, connect the account inside the container:\n\n' +
|
|
172
|
-
' docker compose exec fluxmail fluxmail accounts add outlook\n\n' +
|
|
173
|
-
`Otherwise, stop the process using port ${port} and try again.`, { cause: error });
|
|
174
|
-
}
|
|
175
|
-
export async function runMicrosoftLoopbackFlow(config, onAuthUrl, onAuthorized) {
|
|
150
|
+
export async function runMicrosoftLoopbackFlow(config, onAuthUrl, onAuthorized, options) {
|
|
176
151
|
const oauthClient = { ...requireMicrosoftConfig(config) };
|
|
177
152
|
const redirectUri = `http://localhost:${config.oauthPort}/oauth/microsoft/callback`;
|
|
178
153
|
const state = randomBytes(16).toString('hex');
|
|
179
154
|
const verifier = randomBytes(48).toString('base64url');
|
|
180
|
-
return
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
if (url.searchParams.get('state') !== state) {
|
|
196
|
-
response.writeHead(400).end('State mismatch. Restart the flow.');
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
const oauthError = url.searchParams.get('error');
|
|
200
|
-
if (oauthError) {
|
|
201
|
-
const description = url.searchParams.get('error_description') ?? oauthError;
|
|
202
|
-
finish(() => reject(new EmailError('invalid_request', `Microsoft OAuth error: ${description}`)));
|
|
203
|
-
response.writeHead(400).end(`Microsoft returned an error: ${description}. You can close this tab.`);
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
206
|
-
const code = url.searchParams.get('code');
|
|
207
|
-
if (!code) {
|
|
208
|
-
response.writeHead(400).end('Missing code parameter.');
|
|
209
|
-
return;
|
|
210
|
-
}
|
|
211
|
-
const result = await exchangeMicrosoftCode(config, code, redirectUri, verifier, 'public', oauthClient);
|
|
212
|
-
const accepted = onAuthorized ? await onAuthorized(result) : result;
|
|
213
|
-
finish(() => resolve(accepted));
|
|
214
|
-
response
|
|
215
|
-
.writeHead(200, { 'content-type': 'text/html; charset=utf-8' })
|
|
216
|
-
.end(callbackPage(`${result.email} is connected to Fluxmail`, 'The account is ready to use.'));
|
|
217
|
-
}
|
|
218
|
-
catch (error) {
|
|
219
|
-
finish(() => reject(error));
|
|
220
|
-
const expected = error instanceof EmailError;
|
|
221
|
-
const message = expected
|
|
222
|
-
? error.message
|
|
223
|
-
: 'Fluxmail could not finish connecting this account. Check the terminal for details.';
|
|
224
|
-
response
|
|
225
|
-
.writeHead(expected ? 400 : 500, { 'content-type': 'text/html; charset=utf-8' })
|
|
226
|
-
.end(callbackPage('Fluxmail could not connect this account', message));
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
server.on('error', (error) => reject(listenerError(error, config.oauthPort)));
|
|
230
|
-
server.listen(config.oauthPort, config.oauthHost, () => {
|
|
231
|
-
onAuthUrl(buildMicrosoftAuthUrl(config, redirectUri, state, verifier, oauthClient));
|
|
232
|
-
});
|
|
155
|
+
return runOAuthCallbackFlow({
|
|
156
|
+
provider: 'outlook',
|
|
157
|
+
redirectUri,
|
|
158
|
+
host: config.oauthHost,
|
|
159
|
+
port: config.oauthPort,
|
|
160
|
+
state,
|
|
161
|
+
authUrl: buildMicrosoftAuthUrl(config, redirectUri, state, verifier, oauthClient),
|
|
162
|
+
onAuthUrl,
|
|
163
|
+
complete: async (code) => {
|
|
164
|
+
const result = await exchangeMicrosoftCode(config, code, redirectUri, verifier, 'public', oauthClient);
|
|
165
|
+
const value = onAuthorized ? await onAuthorized(result) : result;
|
|
166
|
+
return { email: result.email, value };
|
|
167
|
+
},
|
|
168
|
+
options,
|
|
233
169
|
});
|
|
234
170
|
}
|
|
235
171
|
//# sourceMappingURL=microsoftAuth.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"microsoftAuth.js","sourceRoot":"","sources":["../../src/accounts/microsoftAuth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"microsoftAuth.js","sourceRoot":"","sources":["../../src/accounts/microsoftAuth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAG5C,OAAO,EAAE,oBAAoB,EAAsD,MAAM,oBAAoB,CAAC;AAE9G,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,QAAQ;IACR,SAAS;IACT,OAAO;IACP,gBAAgB;IAChB,WAAW;IACX,gBAAgB;IAChB,WAAW;IACX,sBAAsB;CACvB,CAAC;AA4BF,MAAM,UAAU,sBAAsB,CAAC,MAAsB;IAC3D,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,MAAM,IAAI,UAAU,CAClB,iBAAiB,EACjB,8JAA8J,CAC/J,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,SAAS,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,4BAA4B,CAAC,MAAsB;IACjE,MAAM,SAAS,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;IACjD,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;QAC5B,+EAA+E;QAC/E,uEAAuE;QACvE,MAAM,IAAI,UAAU,CAClB,iBAAiB,EACjB,CAAC,MAAM,CAAC,mBAAmB;YACzB,CAAC,CAAC,sGAAsG;YACxG,CAAC,CAAC,kDAAkD,CAAC;YACrD,uEAAuE,CAC1E,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,cAAc,CAAC,SAAkC,EAAE,IAA2B;IACrF,OAAO,qCAAqC,kBAAkB,CAAC,SAAS,CAAC,QAAQ,CAAC,gBAAgB,IAAI,EAAE,CAAC;AAC3G,CAAC;AAED,SAAS,aAAa,CAAC,QAAgB;IACrC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;AACnE,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,MAAsB,EACtB,WAAmB,EACnB,KAAa,EACb,QAAgB,EAChB,cAAuC,sBAAsB,CAAC,MAAM,CAAC;IAErE,MAAM,SAAS,GAAG,WAAW,CAAC;IAC9B,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,CAAC;IAC5D,GAAG,CAAC,MAAM,GAAG,IAAI,eAAe,CAAC;QAC/B,SAAS,EAAE,SAAS,CAAC,QAAQ;QAC7B,aAAa,EAAE,MAAM;QACrB,YAAY,EAAE,WAAW;QACzB,aAAa,EAAE,OAAO;QACtB,KAAK,EAAE,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC;QACjC,KAAK;QACL,cAAc,EAAE,aAAa,CAAC,QAAQ,CAAC;QACvC,qBAAqB,EAAE,MAAM;QAC7B,MAAM,EAAE,gBAAgB;KACzB,CAAC,CAAC,QAAQ,EAAE,CAAC;IACd,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,SAAkC,EAClC,MAA8B,EAC9B,UAAqC;IAErC,IAAI,UAAU,KAAK,cAAc,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,CAAC;QAC7D,MAAM,IAAI,UAAU,CAAC,iBAAiB,EAAE,qEAAqE,CAAC,CAAC;IACjH,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,eAAe,CAAC;QAC/B,SAAS,EAAE,SAAS,CAAC,QAAQ;QAC7B,GAAG,MAAM;QACT,GAAG,CAAC,UAAU,KAAK,cAAc,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,SAAS,CAAC,YAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACrF,CAAC,CAAC;IACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,cAAc,CAAC,SAAS,EAAE,OAAO,CAAC,EAAE;QAC/D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,mCAAmC,EAAE;QAChE,IAAI;KACL,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAA2B,CAAC;IAClE,IAAI,CAAC,QAAQ,CAAC,EAAE,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClC,MAAM,MAAM,GAAG,OAAO,CAAC,iBAAiB,IAAI,OAAO,CAAC,KAAK,IAAI,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;QACvF,MAAM,IAAI,GAAG,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,sBAAsB,CAAC;QAClG,MAAM,IAAI,UAAU,CAAC,IAAI,EAAE,2BAA2B,MAAM,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,oBAAoB,CAC3B,OAA+B,EAC/B,UAAqC,EACrC,SAAkC,EAClC,oBAA6B;IAE7B,IAAI,CAAC,OAAO,CAAC,YAAY;QAAE,MAAM,IAAI,UAAU,CAAC,sBAAsB,EAAE,0CAA0C,CAAC,CAAC;IACpH,MAAM,YAAY,GAAG,OAAO,CAAC,aAAa,IAAI,oBAAoB,CAAC;IACnE,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,MAAM,IAAI,UAAU,CAClB,iBAAiB,EACjB,yFAAyF,CAC1F,CAAC;IACJ,CAAC;IACD,OAAO;QACL,WAAW,EAAE,OAAO,CAAC,YAAY;QACjC,YAAY;QACZ,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,UAAU,IAAI,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK;QACzE,UAAU;QACV,mBAAmB,EAAE,EAAE,GAAG,SAAS,EAAE;QACrC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACnD,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,2BAA2B,CAC/C,MAAsB,EACtB,WAAiC;IAEjC,MAAM,SAAS,GAAG,WAAW,CAAC,mBAAmB,IAAI,sBAAsB,CAAC,MAAM,CAAC,CAAC;IACpF,MAAM,UAAU,GAAG,WAAW,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAClG,MAAM,YAAY,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;IAC/C,MAAM,OAAO,GAAG,MAAM,YAAY,CAChC,SAAS,EACT;QACE,UAAU,EAAE,eAAe;QAC3B,aAAa,EAAE,WAAW,CAAC,YAAY;QACvC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACjD,EACD,UAAU,CACX,CAAC;IACF,OAAO,oBAAoB,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;AACxF,CAAC;AAED,KAAK,UAAU,iBAAiB,CAAC,WAAmB;IAClD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,gFAAgF,EAAE;QAC7G,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,WAAW,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;KAChF,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAKrC,CAAC;IACF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,UAAU,CAClB,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,sBAAsB,EACjE,yDAAyD,OAAO,CAAC,KAAK,EAAE,OAAO,IAAI,QAAQ,QAAQ,CAAC,MAAM,EAAE,EAAE,CAC/G,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,iBAAiB,EAAE,IAAI,EAAE,CAAC;IACxE,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,UAAU,CAAC,sBAAsB,EAAE,6CAA6C,CAAC,CAAC;IACxG,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC;IAChD,OAAO,EAAE,KAAK,EAAE,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC5D,CAAC;AAED,KAAK,UAAU,sBAAsB,CAAC,WAAmB;IACvD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,kEAAkE,EAAE;QAC/F,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,WAAW,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE;KAChF,CAAC,CAAC;IACH,IAAI,OAAO,GAAyD,EAAE,CAAC;IACvE,IAAI,CAAC;QACH,OAAO,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAmB,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,oEAAoE;IACtE,CAAC;IACD,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GACR,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,sBAAsB,CAAC;QACpH,MAAM,IAAI,UAAU,CAClB,IAAI,EACJ,4DAA4D,OAAO,CAAC,KAAK,EAAE,OAAO,IAAI,QAAQ,QAAQ,CAAC,MAAM,EAAE,EAAE,CAClH,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;QAChB,MAAM,IAAI,UAAU,CAAC,sBAAsB,EAAE,yDAAyD,CAAC,CAAC;IAC1G,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAsB,EACtB,IAAY,EACZ,WAAmB,EACnB,QAAgB,EAChB,aAAwC,QAAQ,EAChD,cAAuC,sBAAsB,CAAC,MAAM,CAAC;IAErE,MAAM,SAAS,GAAG,EAAE,GAAG,WAAW,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,MAAM,YAAY,CAChC,SAAS,EACT;QACE,UAAU,EAAE,oBAAoB;QAChC,IAAI;QACJ,YAAY,EAAE,WAAW;QACzB,aAAa,EAAE,QAAQ;QACvB,KAAK,EAAE,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC;KAClC,EACD,UAAU,CACX,CAAC;IACF,MAAM,WAAW,GAAG,oBAAoB,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,CAAC,CAAC;IACzE,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;IAClE,MAAM,sBAAsB,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;IACtD,OAAO,EAAE,GAAG,QAAQ,EAAE,WAAW,EAAE,CAAC;AACtC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAC5C,MAAsB,EACtB,SAA8D,EAC9D,YAA+D,EAC/D,OAA6B;IAE7B,MAAM,WAAW,GAAG,EAAE,GAAG,sBAAsB,CAAC,MAAM,CAAC,EAAE,CAAC;IAC1D,MAAM,WAAW,GAAG,oBAAoB,MAAM,CAAC,SAAS,2BAA2B,CAAC;IACpF,MAAM,KAAK,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,WAAW,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;IAEvD,OAAO,oBAAoB,CAAC;QAC1B,QAAQ,EAAE,SAAS;QACnB,WAAW;QACX,IAAI,EAAE,MAAM,CAAC,SAAS;QACtB,IAAI,EAAE,MAAM,CAAC,SAAS;QACtB,KAAK;QACL,OAAO,EAAE,qBAAqB,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,CAAC;QACjF,SAAS;QACT,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YACvB,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;YACvG,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,CAAC,MAAM,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAE,MAAY,CAAC;YACxE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC;QACxC,CAAC;QACD,OAAO;KACR,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Readable } from 'node:stream';
|
|
2
|
+
/** How the authorization code reached the CLI, or `timeout` when it never did. */
|
|
3
|
+
export type OAuthCallbackSource = 'listener' | 'pasted' | 'timeout';
|
|
4
|
+
/**
|
|
5
|
+
* A terminal where the user can paste the callback URL from their browser's
|
|
6
|
+
* address bar. This lets the flow finish when the browser runs on another
|
|
7
|
+
* computer and the redirect cannot reach the CLI's listener.
|
|
8
|
+
*/
|
|
9
|
+
export interface OAuthPasteInput {
|
|
10
|
+
input: Readable;
|
|
11
|
+
/** Prints a follow-up message when a pasted value cannot be used. */
|
|
12
|
+
write: (message: string) => void;
|
|
13
|
+
}
|
|
14
|
+
export interface OAuthAuthUrlContext {
|
|
15
|
+
/** Whether the local listener is accepting the browser redirect. */
|
|
16
|
+
listening: boolean;
|
|
17
|
+
/** Whether the user can paste the callback URL instead. */
|
|
18
|
+
pasteEnabled: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface LoopbackFlowOptions {
|
|
21
|
+
paste?: OAuthPasteInput;
|
|
22
|
+
/** Defaults to 10 minutes. */
|
|
23
|
+
timeoutMs?: number;
|
|
24
|
+
/** Called once: when a callback carrying an authorization code is accepted, or on timeout. */
|
|
25
|
+
onCallback?: (source: OAuthCallbackSource) => void;
|
|
26
|
+
}
|
|
27
|
+
export declare const DEFAULT_OAUTH_CALLBACK_TIMEOUT_MS: number;
|
|
28
|
+
interface CallbackFlowParams<T> {
|
|
29
|
+
provider: 'gmail' | 'outlook';
|
|
30
|
+
redirectUri: string;
|
|
31
|
+
host: string;
|
|
32
|
+
port: number;
|
|
33
|
+
state: string;
|
|
34
|
+
authUrl: string;
|
|
35
|
+
onAuthUrl: (url: string, context: OAuthAuthUrlContext) => void;
|
|
36
|
+
/** Exchanges the code and stores the account. Its errors end the flow. */
|
|
37
|
+
complete: (code: string) => Promise<{
|
|
38
|
+
email: string;
|
|
39
|
+
value: T;
|
|
40
|
+
}>;
|
|
41
|
+
options?: LoopbackFlowOptions;
|
|
42
|
+
}
|
|
43
|
+
/** Explains a busy callback port, including the Docker Compose case where the container owns it. */
|
|
44
|
+
export declare function callbackPortInUseError(error: Error, port: number, provider: 'gmail' | 'outlook'): Error;
|
|
45
|
+
/**
|
|
46
|
+
* Waits for the OAuth redirect on the loopback listener and, when a terminal
|
|
47
|
+
* is available, for the same callback URL pasted into it. The first callback
|
|
48
|
+
* that carries a code wins, and the flow gives up after a timeout.
|
|
49
|
+
*/
|
|
50
|
+
export declare function runOAuthCallbackFlow<T>(params: CallbackFlowParams<T>): Promise<T>;
|
|
51
|
+
export {};
|
|
52
|
+
//# sourceMappingURL=oauthCallback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauthCallback.d.ts","sourceRoot":"","sources":["../../src/accounts/oauthCallback.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5C,kFAAkF;AAClF,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEpE;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,QAAQ,CAAC;IAChB,qEAAqE;IACrE,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,mBAAmB;IAClC,oEAAoE;IACpE,SAAS,EAAE,OAAO,CAAC;IACnB,2DAA2D;IAC3D,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,8BAA8B;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8FAA8F;IAC9F,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACpD;AAED,eAAO,MAAM,iCAAiC,QAAiB,CAAC;AAEhE,UAAU,kBAAkB,CAAC,CAAC;IAC5B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAC/D,0EAA0E;IAC1E,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,CAAC,CAAA;KAAE,CAAC,CAAC;IACjE,OAAO,CAAC,EAAE,mBAAmB,CAAC;CAC/B;AAwED,oGAAoG;AACpG,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,KAAK,CASvG;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,MAAM,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAoLjF"}
|