omnara 0.1.2 → 0.1.3
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/dist/auth/auth-provider.js +1 -1
- package/dist/auth/auth-provider.js.map +1 -1
- package/dist/auth/cli-auth-service.d.ts +11 -2
- package/dist/auth/cli-auth-service.js +22 -5
- package/dist/auth/cli-auth-service.js.map +1 -1
- package/dist/auth/login-flow.js +114 -19
- package/dist/auth/login-flow.js.map +1 -1
- package/dist/auth/loopback-listener.d.ts +20 -0
- package/dist/auth/loopback-listener.js +159 -0
- package/dist/auth/loopback-listener.js.map +1 -0
- package/dist/auth/pkce.d.ts +6 -0
- package/dist/auth/pkce.js +18 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/utils/base64url.d.ts +1 -0
- package/dist/utils/base64url.js +12 -0
- package/dist/utils/base64url.js.map +1 -0
- package/dist/utils/random.d.ts +1 -0
- package/dist/utils/random.js +9 -0
- package/dist/utils/random.js.map +1 -0
- package/package.json +1 -1
|
@@ -28,7 +28,7 @@ class AuthProvider {
|
|
|
28
28
|
if (!shouldAttemptLogin(error)) {
|
|
29
29
|
throw error;
|
|
30
30
|
}
|
|
31
|
-
this.options.logger?.log('
|
|
31
|
+
this.options.logger?.log('Opening browser to authenticate…');
|
|
32
32
|
await (0, login_flow_1.performVerificationLogin)({
|
|
33
33
|
backendUrlOption: this.backendUrl,
|
|
34
34
|
frontendUrlOption: this.options.frontendUrl,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth-provider.js","sourceRoot":"","sources":["../../src/auth/auth-provider.ts"],"names":[],"mappings":";;;AAiEA,gDAIC;AAlED,6DAA2E;AAC3E,6CAAwD;AACxD,mDAAsD;AAStD,MAAa,YAAY;IAIvB,YAA6B,OAA4B;QAA5B,YAAO,GAAP,OAAO,CAAqB;QAHjD,WAAM,GAAuB,IAAI,CAAC;QAIxC,IAAI,CAAC,UAAU,GAAG,IAAA,6BAAgB,EAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC1C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QACzC,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,IAAI,CAAC;YACH,OAAO,MAAM,IAAA,sCAAiB,EAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACtE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC/B,MAAM,KAAK,CAAC;YACd,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,
|
|
1
|
+
{"version":3,"file":"auth-provider.js","sourceRoot":"","sources":["../../src/auth/auth-provider.ts"],"names":[],"mappings":";;;AAiEA,gDAIC;AAlED,6DAA2E;AAC3E,6CAAwD;AACxD,mDAAsD;AAStD,MAAa,YAAY;IAIvB,YAA6B,OAA4B;QAA5B,YAAO,GAAP,OAAO,CAAqB;QAHjD,WAAM,GAAuB,IAAI,CAAC;QAIxC,IAAI,CAAC,UAAU,GAAG,IAAA,6BAAgB,EAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC1C,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,cAAc;QAClB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QACzC,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAEO,KAAK,CAAC,eAAe;QAC3B,IAAI,CAAC;YACH,OAAO,MAAM,IAAA,sCAAiB,EAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACtE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC/B,MAAM,KAAK,CAAC;YACd,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,kCAAkC,CAAC,CAAC;YAC7D,MAAM,IAAA,qCAAwB,EAAC;gBAC7B,gBAAgB,EAAE,IAAI,CAAC,UAAU;gBACjC,iBAAiB,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW;gBAC3C,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,KAAK;aAC1B,CAAC,CAAC;YACH,OAAO,MAAM,IAAA,sCAAiB,EAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;CACF;AAnCD,oCAmCC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IAC5C,OAAO,CACL,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC;QACxC,OAAO,CAAC,QAAQ,CAAC,+BAA+B,CAAC;QACjD,OAAO,CAAC,QAAQ,CAAC,uBAAuB,CAAC;QACzC,OAAO,CAAC,QAAQ,CAAC,2BAA2B,CAAC;QAC7C,OAAO,CAAC,QAAQ,CAAC,sBAAsB,CAAC,CACzC,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,kBAAkB,CAAC,OAA4B;IACnE,MAAM,QAAQ,GAAG,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;IAC3C,MAAM,QAAQ,CAAC,cAAc,EAAE,CAAC;IAChC,OAAO,QAAQ,CAAC;AAClB,CAAC"}
|
|
@@ -6,6 +6,13 @@ export interface CliAuthSession {
|
|
|
6
6
|
expiresIn: number;
|
|
7
7
|
pollInterval: number;
|
|
8
8
|
}
|
|
9
|
+
export interface CreateCliAuthSessionOptions {
|
|
10
|
+
frontendUrl?: string;
|
|
11
|
+
loopbackRedirectUri?: string;
|
|
12
|
+
loopbackState?: string;
|
|
13
|
+
pkceChallenge?: string;
|
|
14
|
+
pkceChallengeMethod?: string;
|
|
15
|
+
}
|
|
9
16
|
export interface ExchangeCliCodeResult {
|
|
10
17
|
accessToken: string;
|
|
11
18
|
accessTokenExpiresIn: number;
|
|
@@ -14,5 +21,7 @@ export interface ExchangeCliCodeResult {
|
|
|
14
21
|
relayWsPath: string;
|
|
15
22
|
relayHeartbeatIntervalSec: number;
|
|
16
23
|
}
|
|
17
|
-
export declare function createCliAuthSession(client: ApiClient,
|
|
18
|
-
export declare function exchangeCliCode(client: ApiClient, sessionId: string, code: string
|
|
24
|
+
export declare function createCliAuthSession(client: ApiClient, options?: CreateCliAuthSessionOptions): Promise<CliAuthSession>;
|
|
25
|
+
export declare function exchangeCliCode(client: ApiClient, sessionId: string, code: string, options?: {
|
|
26
|
+
codeVerifier?: string;
|
|
27
|
+
}): Promise<ExchangeCliCodeResult>;
|
|
@@ -2,8 +2,21 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createCliAuthSession = createCliAuthSession;
|
|
4
4
|
exports.exchangeCliCode = exchangeCliCode;
|
|
5
|
-
async function createCliAuthSession(client,
|
|
6
|
-
const body =
|
|
5
|
+
async function createCliAuthSession(client, options = {}) {
|
|
6
|
+
const body = {};
|
|
7
|
+
if (options.frontendUrl) {
|
|
8
|
+
body.frontend_url = options.frontendUrl;
|
|
9
|
+
}
|
|
10
|
+
if (options.loopbackRedirectUri) {
|
|
11
|
+
body.loopback_redirect_uri = options.loopbackRedirectUri;
|
|
12
|
+
}
|
|
13
|
+
if (options.loopbackState) {
|
|
14
|
+
body.loopback_state = options.loopbackState;
|
|
15
|
+
}
|
|
16
|
+
if (options.pkceChallenge) {
|
|
17
|
+
body.pkce_challenge = options.pkceChallenge;
|
|
18
|
+
body.pkce_challenge_method = options.pkceChallengeMethod ?? 'S256';
|
|
19
|
+
}
|
|
7
20
|
const wire = await client.postJson('/api/v1/cli-auth/session', body);
|
|
8
21
|
return {
|
|
9
22
|
sessionId: wire.session_id,
|
|
@@ -13,11 +26,15 @@ async function createCliAuthSession(client, frontendUrl) {
|
|
|
13
26
|
pollInterval: wire.poll_interval,
|
|
14
27
|
};
|
|
15
28
|
}
|
|
16
|
-
async function exchangeCliCode(client, sessionId, code) {
|
|
17
|
-
const
|
|
29
|
+
async function exchangeCliCode(client, sessionId, code, options = {}) {
|
|
30
|
+
const requestBody = {
|
|
18
31
|
session_id: sessionId,
|
|
19
32
|
code,
|
|
20
|
-
}
|
|
33
|
+
};
|
|
34
|
+
if (options.codeVerifier) {
|
|
35
|
+
requestBody.code_verifier = options.codeVerifier;
|
|
36
|
+
}
|
|
37
|
+
const wire = await client.postJson('/api/v1/cli-auth/exchange', requestBody);
|
|
21
38
|
return {
|
|
22
39
|
accessToken: wire.access_token,
|
|
23
40
|
accessTokenExpiresIn: wire.access_token_expires_in,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli-auth-service.js","sourceRoot":"","sources":["../../src/auth/cli-auth-service.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"cli-auth-service.js","sourceRoot":"","sources":["../../src/auth/cli-auth-service.ts"],"names":[],"mappings":";;AA0DA,oDA6BC;AAED,0CA0BC;AAzDM,KAAK,UAAU,oBAAoB,CACxC,MAAiB,EACjB,UAAuC,EAAE;IAEzC,MAAM,IAAI,GAA6B,EAAE,CAAC;IAC1C,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC;QACxB,IAAI,CAAC,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC;IAC1C,CAAC;IACD,IAAI,OAAO,CAAC,mBAAmB,EAAE,CAAC;QAChC,IAAI,CAAC,qBAAqB,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAC3D,CAAC;IACD,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QAC1B,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;IAC9C,CAAC;IACD,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;QAC1B,IAAI,CAAC,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC;QAC5C,IAAI,CAAC,qBAAqB,GAAG,OAAO,CAAC,mBAAmB,IAAI,MAAM,CAAC;IACrE,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,CAChC,0BAA0B,EAC1B,IAAI,CACL,CAAC;IACF,OAAO;QACL,SAAS,EAAE,IAAI,CAAC,UAAU;QAC1B,eAAe,EAAE,IAAI,CAAC,gBAAgB;QACtC,uBAAuB,EAAE,IAAI,CAAC,yBAAyB;QACvD,SAAS,EAAE,IAAI,CAAC,UAAU;QAC1B,YAAY,EAAE,IAAI,CAAC,aAAa;KACjC,CAAC;AACJ,CAAC;AAEM,KAAK,UAAU,eAAe,CACnC,MAAiB,EACjB,SAAiB,EACjB,IAAY,EACZ,UAAqC,EAAE;IAEvC,MAAM,WAAW,GAAwB;QACvC,UAAU,EAAE,SAAS;QACrB,IAAI;KACL,CAAC;IACF,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACzB,WAAW,CAAC,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IACnD,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,QAAQ,CAChC,2BAA2B,EAC3B,WAAW,CACZ,CAAC;IACF,OAAO;QACL,WAAW,EAAE,IAAI,CAAC,YAAY;QAC9B,oBAAoB,EAAE,IAAI,CAAC,uBAAuB;QAClD,YAAY,EAAE,IAAI,CAAC,aAAa;QAChC,qBAAqB,EAAE,IAAI,CAAC,wBAAwB;QACpD,WAAW,EAAE,IAAI,CAAC,aAAa;QAC/B,yBAAyB,EAAE,IAAI,CAAC,4BAA4B;KAC7D,CAAC;AACJ,CAAC"}
|
package/dist/auth/login-flow.js
CHANGED
|
@@ -9,38 +9,100 @@ const child_process_1 = require("child_process");
|
|
|
9
9
|
const api_client_1 = require("../http/api-client");
|
|
10
10
|
const prompt_1 = require("../utils/prompt");
|
|
11
11
|
const cli_auth_service_1 = require("./cli-auth-service");
|
|
12
|
+
const pkce_1 = require("./pkce");
|
|
13
|
+
const loopback_listener_1 = require("./loopback-listener");
|
|
12
14
|
async function performVerificationLogin({ backendUrlOption, frontendUrlOption, store, }) {
|
|
13
15
|
const backendUrl = resolveBackendUrl(backendUrlOption);
|
|
14
16
|
const frontendUrl = resolveFrontendUrl(frontendUrlOption);
|
|
15
17
|
const client = new api_client_1.ApiClient({ baseUrl: backendUrl });
|
|
16
|
-
console.log('\
|
|
17
|
-
const
|
|
18
|
+
console.log('\nAuthenticating CLI…');
|
|
19
|
+
const loopback = await loopback_listener_1.LoopbackListener.create();
|
|
20
|
+
const pkce = loopback ? (0, pkce_1.generatePkcePair)() : null;
|
|
21
|
+
const sessionOptions = {
|
|
22
|
+
frontendUrl,
|
|
23
|
+
};
|
|
24
|
+
if (loopback && pkce) {
|
|
25
|
+
sessionOptions.loopbackRedirectUri = loopback.redirectUri;
|
|
26
|
+
sessionOptions.loopbackState = loopback.state;
|
|
27
|
+
sessionOptions.pkceChallenge = pkce.challenge;
|
|
28
|
+
sessionOptions.pkceChallengeMethod = pkce.method;
|
|
29
|
+
}
|
|
30
|
+
const session = await (0, cli_auth_service_1.createCliAuthSession)(client, sessionOptions);
|
|
18
31
|
printSessionInstructions(session);
|
|
19
32
|
tryOpenBrowser(session.verificationUriComplete);
|
|
20
|
-
|
|
21
|
-
|
|
33
|
+
let completed = false;
|
|
34
|
+
let successLogged = false;
|
|
35
|
+
let latestCredentials = null;
|
|
36
|
+
const completeLogin = async (code, codeVerifier) => {
|
|
37
|
+
if (completed) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const exchange = await (0, cli_auth_service_1.exchangeCliCode)(client, session.sessionId, code, codeVerifier ? { codeVerifier } : {});
|
|
41
|
+
const updated = mergeCredentialsAfterExchange({
|
|
42
|
+
exchange,
|
|
43
|
+
});
|
|
44
|
+
await store.save(updated);
|
|
45
|
+
latestCredentials = updated;
|
|
46
|
+
if (!successLogged) {
|
|
47
|
+
console.log('\nLogin successful. Credentials saved.');
|
|
48
|
+
successLogged = true;
|
|
49
|
+
}
|
|
50
|
+
completed = true;
|
|
51
|
+
};
|
|
52
|
+
const loopbackTask = loopback && pkce
|
|
53
|
+
? waitForLoopback(loopback, session.sessionId, async (code) => {
|
|
54
|
+
await completeLogin(code, pkce.verifier);
|
|
55
|
+
if (typeof process.stdin.emit === 'function') {
|
|
56
|
+
process.stdin.emit('data', '\n');
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
: null;
|
|
60
|
+
if (!loopbackTask && !completed) {
|
|
61
|
+
console.log('\nWaiting for approval in the browser…');
|
|
62
|
+
}
|
|
63
|
+
while (!completed) {
|
|
64
|
+
const input = await (0, prompt_1.prompt)('\nFallback code if automatic login doesn\'t complete: ');
|
|
22
65
|
const cleaned = input.trim();
|
|
66
|
+
if (completed) {
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
if (!cleaned) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
23
72
|
if (!/^[0-9]{6}$/.test(cleaned)) {
|
|
24
73
|
console.log('Codes must be exactly six digits.');
|
|
25
74
|
continue;
|
|
26
75
|
}
|
|
27
76
|
try {
|
|
28
|
-
|
|
29
|
-
const updated = mergeCredentialsAfterExchange({
|
|
30
|
-
exchange,
|
|
31
|
-
});
|
|
32
|
-
await store.save(updated);
|
|
33
|
-
console.log('\nLogin successful. Credentials saved.');
|
|
34
|
-
return updated;
|
|
77
|
+
await completeLogin(cleaned);
|
|
35
78
|
}
|
|
36
79
|
catch (error) {
|
|
37
|
-
if (error instanceof api_client_1.ApiError
|
|
38
|
-
|
|
39
|
-
|
|
80
|
+
if (error instanceof api_client_1.ApiError) {
|
|
81
|
+
if (error.status === 401) {
|
|
82
|
+
console.log('Code not recognized. Double-check the digits shown in the browser.');
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
if (error.status === 409) {
|
|
86
|
+
console.log('Browser approval already completed. Finishing up…');
|
|
87
|
+
completed = true;
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
40
90
|
}
|
|
91
|
+
await loopback?.stop();
|
|
41
92
|
throw error;
|
|
42
93
|
}
|
|
43
94
|
}
|
|
95
|
+
await loopback?.stop();
|
|
96
|
+
if (!latestCredentials) {
|
|
97
|
+
const stored = await store.load();
|
|
98
|
+
if (stored) {
|
|
99
|
+
latestCredentials = stored;
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
throw new Error('Login completed but credentials were not stored.');
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return latestCredentials;
|
|
44
106
|
}
|
|
45
107
|
const DEFAULT_BACKEND_URL = 'https://omnara-voice.onrender.com/';
|
|
46
108
|
const DEFAULT_FRONTEND_URL = 'https://voice.omnara.com/';
|
|
@@ -82,12 +144,17 @@ function formatDuration(ms) {
|
|
|
82
144
|
const hours = totalDays % 24;
|
|
83
145
|
return hours > 0 ? `${totalDays}d ${hours}h` : `${totalDays}d`;
|
|
84
146
|
}
|
|
147
|
+
function reportLoopbackError(error) {
|
|
148
|
+
if (error instanceof api_client_1.ApiError) {
|
|
149
|
+
console.log(`Automatic login failed (HTTP ${error.status}). Paste the 6-digit code shown in the browser.`);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
console.log(`Automatic login failed: ${extractErrorMessage(error)}`);
|
|
153
|
+
}
|
|
85
154
|
function printSessionInstructions(session) {
|
|
86
|
-
console.log('\
|
|
87
|
-
console.log(`
|
|
88
|
-
console.log('
|
|
89
|
-
console.log(` This link expires in about ${formatDuration(session.expiresIn * 1000)}.`);
|
|
90
|
-
console.log('\n3. Return here and paste the 6-digit code when prompted.');
|
|
155
|
+
console.log('\nOpen this link in your browser if it did not open automatically:');
|
|
156
|
+
console.log(` ${session.verificationUriComplete}`);
|
|
157
|
+
console.log('Approve the request, then return to the CLI.');
|
|
91
158
|
}
|
|
92
159
|
function tryOpenBrowser(url) {
|
|
93
160
|
const command = process.platform === 'darwin'
|
|
@@ -104,4 +171,32 @@ function tryOpenBrowser(url) {
|
|
|
104
171
|
// Ignore failures; user can open manually.
|
|
105
172
|
}
|
|
106
173
|
}
|
|
174
|
+
function extractErrorMessage(error) {
|
|
175
|
+
if (error instanceof Error && error.message) {
|
|
176
|
+
return error.message;
|
|
177
|
+
}
|
|
178
|
+
return String(error);
|
|
179
|
+
}
|
|
180
|
+
async function waitForLoopback(listener, sessionId, onCode) {
|
|
181
|
+
try {
|
|
182
|
+
const callback = await listener.waitForCallback();
|
|
183
|
+
if (callback.sessionId && callback.sessionId !== sessionId) {
|
|
184
|
+
console.log('Received browser callback for a different session.');
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (callback.state && callback.state !== listener.state) {
|
|
188
|
+
console.log('Received browser callback with unexpected state.');
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
await onCode(callback.code);
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
reportLoopbackError(error);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
console.log(`Loopback listener error: ${extractErrorMessage(error)}`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
107
202
|
//# sourceMappingURL=login-flow.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login-flow.js","sourceRoot":"","sources":["../../src/auth/login-flow.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"login-flow.js","sourceRoot":"","sources":["../../src/auth/login-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface LoopbackCallback {
|
|
2
|
+
code: string;
|
|
3
|
+
sessionId: string | null;
|
|
4
|
+
state: string | null;
|
|
5
|
+
}
|
|
6
|
+
export declare class LoopbackListener {
|
|
7
|
+
static create(): Promise<LoopbackListener | null>;
|
|
8
|
+
readonly state: string;
|
|
9
|
+
redirectUri: string;
|
|
10
|
+
private readonly server;
|
|
11
|
+
private resolveCallback;
|
|
12
|
+
private rejectCallback;
|
|
13
|
+
private pending;
|
|
14
|
+
private constructor();
|
|
15
|
+
waitForCallback(): Promise<LoopbackCallback>;
|
|
16
|
+
stop(): Promise<void>;
|
|
17
|
+
private start;
|
|
18
|
+
private handleRequest;
|
|
19
|
+
private respond;
|
|
20
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LoopbackListener = void 0;
|
|
7
|
+
const http_1 = __importDefault(require("http"));
|
|
8
|
+
const crypto_1 = require("crypto");
|
|
9
|
+
const CALLBACK_PATH = '/callback';
|
|
10
|
+
const LISTEN_HOST = '127.0.0.1';
|
|
11
|
+
class LoopbackListener {
|
|
12
|
+
static async create() {
|
|
13
|
+
const listener = new LoopbackListener(generateState());
|
|
14
|
+
try {
|
|
15
|
+
await listener.start();
|
|
16
|
+
return listener;
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
await listener.stop().catch(() => undefined);
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
constructor(state) {
|
|
24
|
+
this.resolveCallback = null;
|
|
25
|
+
this.rejectCallback = null;
|
|
26
|
+
this.pending = null;
|
|
27
|
+
this.state = state;
|
|
28
|
+
this.redirectUri = '';
|
|
29
|
+
this.server = http_1.default.createServer((request, response) => {
|
|
30
|
+
void this.handleRequest(request, response);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
async waitForCallback() {
|
|
34
|
+
if (this.pending) {
|
|
35
|
+
return this.pending;
|
|
36
|
+
}
|
|
37
|
+
this.pending = new Promise((resolve, reject) => {
|
|
38
|
+
this.resolveCallback = resolve;
|
|
39
|
+
this.rejectCallback = reject;
|
|
40
|
+
});
|
|
41
|
+
return this.pending;
|
|
42
|
+
}
|
|
43
|
+
async stop() {
|
|
44
|
+
if (!this.server.listening) {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
await new Promise((resolve) => {
|
|
48
|
+
this.server.close(() => resolve());
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
async start() {
|
|
52
|
+
await new Promise((resolve, reject) => {
|
|
53
|
+
this.server.once('error', reject);
|
|
54
|
+
this.server.listen(0, LISTEN_HOST, () => {
|
|
55
|
+
this.server.removeListener('error', reject);
|
|
56
|
+
resolve();
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
const address = this.server.address();
|
|
60
|
+
if (!address || typeof address === 'string') {
|
|
61
|
+
throw new Error('Loopback listener failed to bind');
|
|
62
|
+
}
|
|
63
|
+
const { port } = address;
|
|
64
|
+
this.redirectUri = `http://${LISTEN_HOST}:${port}${CALLBACK_PATH}`;
|
|
65
|
+
}
|
|
66
|
+
async handleRequest(request, response) {
|
|
67
|
+
if (request.method !== 'GET' || !request.url) {
|
|
68
|
+
this.respond(response, 405, 'Method Not Allowed');
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const url = new URL(request.url, `http://${request.headers.host ?? LISTEN_HOST}`);
|
|
72
|
+
if (url.pathname !== CALLBACK_PATH) {
|
|
73
|
+
this.respond(response, 404, 'Not Found');
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const code = url.searchParams.get('code');
|
|
77
|
+
const sessionId = url.searchParams.get('session');
|
|
78
|
+
const state = url.searchParams.get('state');
|
|
79
|
+
if (!code) {
|
|
80
|
+
this.respond(response, 400, buildMessageHtml('Missing authorization code. Return to your CLI and try again.'));
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
this.respond(response, 200, buildSuccessHtml());
|
|
84
|
+
if (this.resolveCallback) {
|
|
85
|
+
this.resolveCallback({ code, sessionId, state });
|
|
86
|
+
this.resolveCallback = null;
|
|
87
|
+
this.rejectCallback = null;
|
|
88
|
+
}
|
|
89
|
+
void this.stop();
|
|
90
|
+
}
|
|
91
|
+
respond(response, status, body) {
|
|
92
|
+
response.writeHead(status, {
|
|
93
|
+
'content-type': 'text/html; charset=utf-8',
|
|
94
|
+
'cache-control': 'no-store',
|
|
95
|
+
});
|
|
96
|
+
response.end(body);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.LoopbackListener = LoopbackListener;
|
|
100
|
+
function buildSuccessHtml() {
|
|
101
|
+
const redirectTarget = 'https://voice.omnara.com/dashboard';
|
|
102
|
+
return `<!doctype html>
|
|
103
|
+
<html lang="en">
|
|
104
|
+
<head>
|
|
105
|
+
<meta charset="utf-8" />
|
|
106
|
+
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
107
|
+
<meta http-equiv="refresh" content="3;url=${redirectTarget}" />
|
|
108
|
+
<title>Omnara CLI Login</title>
|
|
109
|
+
<style>
|
|
110
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #090909; color: #f4f4f5; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; }
|
|
111
|
+
.card { max-width: 420px; padding: 2.5rem; background: rgba(32, 32, 36, 0.85); border-radius: 14px; box-shadow: 0 20px 40px rgba(0,0,0,0.35); text-align: center; }
|
|
112
|
+
h1 { font-size: 1.5rem; margin-bottom: 0.75rem; }
|
|
113
|
+
p { margin: 0 0 0.75rem; line-height: 1.5; }
|
|
114
|
+
.note { font-size: 0.85rem; color: rgba(244,244,245,0.7); }
|
|
115
|
+
</style>
|
|
116
|
+
</head>
|
|
117
|
+
<body>
|
|
118
|
+
<div class="card">
|
|
119
|
+
<h1>Redirecting back to the CLI…</h1>
|
|
120
|
+
<p>Your authentication details were sent to the Omnara CLI. Return to your terminal to continue.</p>
|
|
121
|
+
<p class="note">If this page doesn't close automatically, you can manually open the Omnara dashboard.</p>
|
|
122
|
+
</div>
|
|
123
|
+
</body>
|
|
124
|
+
</html>`;
|
|
125
|
+
}
|
|
126
|
+
function generateState() {
|
|
127
|
+
return base64UrlEncode((0, crypto_1.randomBytes)(32));
|
|
128
|
+
}
|
|
129
|
+
function base64UrlEncode(input) {
|
|
130
|
+
const buffer = typeof input === 'string' ? Buffer.from(input, 'utf8') : Buffer.from(input);
|
|
131
|
+
return buffer
|
|
132
|
+
.toString('base64')
|
|
133
|
+
.replace(/\+/g, '-')
|
|
134
|
+
.replace(/\//g, '_')
|
|
135
|
+
.replace(/=+$/g, '');
|
|
136
|
+
}
|
|
137
|
+
function buildMessageHtml(message) {
|
|
138
|
+
return `<!doctype html>
|
|
139
|
+
<html lang="en">
|
|
140
|
+
<head>
|
|
141
|
+
<meta charset="utf-8" />
|
|
142
|
+
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
|
143
|
+
<title>Omnara CLI Login</title>
|
|
144
|
+
<style>
|
|
145
|
+
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #090909; color: #f4f4f5; display: flex; align-items: center; justify-content: center; min-height: 100vh; margin: 0; }
|
|
146
|
+
.card { max-width: 420px; padding: 2.5rem; background: rgba(32, 32, 36, 0.85); border-radius: 14px; box-shadow: 0 20px 40px rgba(0,0,0,0.35); text-align: center; }
|
|
147
|
+
h1 { font-size: 1.4rem; margin-bottom: 0.75rem; }
|
|
148
|
+
p { margin: 0; line-height: 1.6; }
|
|
149
|
+
</style>
|
|
150
|
+
</head>
|
|
151
|
+
<body>
|
|
152
|
+
<div class="card">
|
|
153
|
+
<h1>Omnara CLI Login</h1>
|
|
154
|
+
<p>${message}</p>
|
|
155
|
+
</div>
|
|
156
|
+
</body>
|
|
157
|
+
</html>`;
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=loopback-listener.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loopback-listener.js","sourceRoot":"","sources":["../../src/auth/loopback-listener.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generatePkcePair = generatePkcePair;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
5
|
+
function generatePkcePair() {
|
|
6
|
+
const verifier = base64UrlEncode((0, crypto_1.randomBytes)(32));
|
|
7
|
+
const challenge = base64UrlEncode((0, crypto_1.createHash)('sha256').update(verifier).digest());
|
|
8
|
+
return { verifier, challenge, method: 'S256' };
|
|
9
|
+
}
|
|
10
|
+
function base64UrlEncode(input) {
|
|
11
|
+
const buffer = typeof input === 'string' ? Buffer.from(input, 'utf8') : Buffer.from(input);
|
|
12
|
+
return buffer
|
|
13
|
+
.toString('base64')
|
|
14
|
+
.replace(/\+/g, '-')
|
|
15
|
+
.replace(/\//g, '_')
|
|
16
|
+
.replace(/=+$/g, '');
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=pkce.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pkce.js","sourceRoot":"","sources":["../../src/auth/pkce.ts"],"names":[],"mappings":";;AAQA,4CAIC;AAZD,mCAAiD;AAQjD,SAAgB,gBAAgB;IAC9B,MAAM,QAAQ,GAAG,eAAe,CAAC,IAAA,oBAAW,EAAC,EAAE,CAAC,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,eAAe,CAAC,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC;IAClF,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACjD,CAAC;AAED,SAAS,eAAe,CAAC,KAAmC;IAC1D,MAAM,MAAM,GACV,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAA4B,CAAC,CAAC;IACrG,OAAO,MAAM;SACV,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function base64UrlEncode(input: Buffer | Uint8Array | string): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.base64UrlEncode = base64UrlEncode;
|
|
4
|
+
function base64UrlEncode(input) {
|
|
5
|
+
const buffer = typeof input === 'string' ? Buffer.from(input, 'utf8') : Buffer.from(input);
|
|
6
|
+
return buffer
|
|
7
|
+
.toString('base64')
|
|
8
|
+
.replace(/\+/g, '-')
|
|
9
|
+
.replace(/\//g, '_')
|
|
10
|
+
.replace(/=+$/g, '');
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=base64url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base64url.js","sourceRoot":"","sources":["../../src/utils/base64url.ts"],"names":[],"mappings":";;AAAA,0CAQC;AARD,SAAgB,eAAe,CAAC,KAAmC;IACjE,MAAM,MAAM,GACV,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAA4B,CAAC,CAAC;IACrG,OAAO,MAAM;SACV,QAAQ,CAAC,QAAQ,CAAC;SAClB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function createRandomState(byteLength?: number): string;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createRandomState = createRandomState;
|
|
4
|
+
const crypto_1 = require("crypto");
|
|
5
|
+
const base64url_1 = require("./base64url");
|
|
6
|
+
function createRandomState(byteLength = 32) {
|
|
7
|
+
return (0, base64url_1.base64UrlEncode)((0, crypto_1.randomBytes)(byteLength));
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=random.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"random.js","sourceRoot":"","sources":["../../src/utils/random.ts"],"names":[],"mappings":";;AAIA,8CAEC;AAND,mCAAqC;AAErC,2CAA8C;AAE9C,SAAgB,iBAAiB,CAAC,UAAU,GAAG,EAAE;IAC/C,OAAO,IAAA,2BAAe,EAAC,IAAA,oBAAW,EAAC,UAAU,CAAC,CAAC,CAAC;AAClD,CAAC"}
|