@noodleseed/one 0.62.0 → 0.63.1
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/bin.js +8 -2
- package/dist/bin.js.map +1 -1
- package/dist/browser.d.ts +10 -0
- package/dist/browser.d.ts.map +1 -0
- package/dist/browser.js +18 -0
- package/dist/browser.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/apps-ops.js +1 -1
- package/dist/commands/apps-ops.js.map +1 -1
- package/dist/commands/deploy-ops.d.ts +2 -3
- package/dist/commands/deploy-ops.d.ts.map +1 -1
- package/dist/commands/deploy-ops.js +5 -17
- package/dist/commands/deploy-ops.js.map +1 -1
- package/dist/commands/github-ops.d.ts +3 -2
- package/dist/commands/github-ops.d.ts.map +1 -1
- package/dist/commands/github-ops.js +7 -4
- package/dist/commands/github-ops.js.map +1 -1
- package/dist/control-plane.d.ts +2 -1
- package/dist/control-plane.d.ts.map +1 -1
- package/dist/control-plane.js +31 -10
- package/dist/control-plane.js.map +1 -1
- package/dist/device-login.d.ts +30 -0
- package/dist/device-login.d.ts.map +1 -0
- package/dist/device-login.js +162 -0
- package/dist/device-login.js.map +1 -0
- package/dist/doctor.d.ts.map +1 -1
- package/dist/doctor.js +11 -0
- package/dist/doctor.js.map +1 -1
- package/dist/platform-support.d.ts +22 -0
- package/dist/platform-support.d.ts.map +1 -0
- package/dist/platform-support.js +118 -0
- package/dist/platform-support.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/app.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/app.js +65 -0
- package/node_modules/@noodle-borg/service/dist/oauth/app.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/branding.d.ts +2 -0
- package/node_modules/@noodle-borg/service/dist/oauth/branding.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/branding.js +3 -2
- package/node_modules/@noodle-borg/service/dist/oauth/branding.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-page.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-page.js +216 -28
- package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-page.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/device-flow.d.ts +20 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-flow.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-flow.js +239 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-flow.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-provider.d.ts +15 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-provider.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-provider.js +45 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-provider.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store-postgres-schema.d.ts +3 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store-postgres-schema.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store-postgres-schema.js +33 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store-postgres-schema.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store-postgres-types.d.ts +30 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store-postgres-types.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store-postgres-types.js +31 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store-postgres-types.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store.d.ts +66 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store.js +2 -0
- package/node_modules/@noodle-borg/service/dist/oauth/device-store.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/paths.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/paths.js +3 -0
- package/node_modules/@noodle-borg/service/dist/oauth/paths.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/provider.d.ts +7 -0
- package/node_modules/@noodle-borg/service/dist/oauth/provider.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/provider.js +36 -1
- package/node_modules/@noodle-borg/service/dist/oauth/provider.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/store-postgres.d.ts +14 -0
- package/node_modules/@noodle-borg/service/dist/oauth/store-postgres.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/store-postgres.js +122 -0
- package/node_modules/@noodle-borg/service/dist/oauth/store-postgres.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/store.d.ts +15 -1
- package/node_modules/@noodle-borg/service/dist/oauth/store.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/store.js +83 -0
- package/node_modules/@noodle-borg/service/dist/oauth/store.js.map +1 -1
- package/node_modules/bundle-name/index.js +5 -0
- package/node_modules/bundle-name/license +9 -0
- package/node_modules/bundle-name/package.json +45 -0
- package/node_modules/bundle-name/readme.md +23 -0
- package/node_modules/default-browser/index.d.ts +29 -0
- package/node_modules/default-browser/index.js +34 -0
- package/node_modules/default-browser/license +9 -0
- package/node_modules/default-browser/package.json +54 -0
- package/node_modules/default-browser/readme.md +24 -0
- package/node_modules/default-browser/windows.js +57 -0
- package/node_modules/default-browser-id/index.js +25 -0
- package/node_modules/default-browser-id/license +9 -0
- package/node_modules/default-browser-id/package.json +41 -0
- package/node_modules/default-browser-id/readme.md +19 -0
- package/node_modules/define-lazy-prop/index.d.ts +31 -0
- package/node_modules/define-lazy-prop/index.js +18 -0
- package/node_modules/define-lazy-prop/license +9 -0
- package/node_modules/define-lazy-prop/package.json +51 -0
- package/node_modules/define-lazy-prop/readme.md +55 -0
- package/node_modules/is-docker/cli.js +5 -0
- package/node_modules/is-docker/index.d.ts +13 -0
- package/node_modules/is-docker/index.js +29 -0
- package/node_modules/is-docker/license +9 -0
- package/node_modules/is-docker/package.json +44 -0
- package/node_modules/is-docker/readme.md +27 -0
- package/node_modules/is-in-ssh/index.d.ts +15 -0
- package/node_modules/is-in-ssh/index.js +7 -0
- package/node_modules/is-in-ssh/license +9 -0
- package/node_modules/is-in-ssh/package.json +43 -0
- package/node_modules/is-in-ssh/readme.md +43 -0
- package/node_modules/is-inside-container/cli.js +5 -0
- package/node_modules/is-inside-container/index.d.ts +13 -0
- package/node_modules/is-inside-container/index.js +23 -0
- package/node_modules/is-inside-container/license +9 -0
- package/node_modules/is-inside-container/package.json +51 -0
- package/node_modules/is-inside-container/readme.md +36 -0
- package/node_modules/is-wsl/index.d.ts +15 -0
- package/node_modules/is-wsl/index.js +36 -0
- package/node_modules/is-wsl/license +9 -0
- package/node_modules/is-wsl/package.json +58 -0
- package/node_modules/is-wsl/readme.md +21 -0
- package/node_modules/open/index.d.ts +158 -0
- package/node_modules/open/index.js +417 -0
- package/node_modules/open/license +9 -0
- package/node_modules/open/package.json +70 -0
- package/node_modules/open/readme.md +197 -0
- package/node_modules/open/xdg-open +1267 -0
- package/node_modules/powershell-utils/index.d.ts +122 -0
- package/node_modules/powershell-utils/index.js +58 -0
- package/node_modules/powershell-utils/license +9 -0
- package/node_modules/powershell-utils/package.json +47 -0
- package/node_modules/powershell-utils/readme.md +153 -0
- package/node_modules/run-applescript/index.d.ts +66 -0
- package/node_modules/run-applescript/index.js +37 -0
- package/node_modules/run-applescript/license +9 -0
- package/node_modules/run-applescript/package.json +42 -0
- package/node_modules/run-applescript/readme.md +78 -0
- package/node_modules/wsl-utils/index.d.ts +81 -0
- package/node_modules/wsl-utils/index.js +98 -0
- package/node_modules/wsl-utils/license +9 -0
- package/node_modules/wsl-utils/package.json +48 -0
- package/node_modules/wsl-utils/readme.md +111 -0
- package/node_modules/wsl-utils/utilities.js +19 -0
- package/package.json +14 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-flow.d.ts","sourceRoot":"","sources":["../../src/oauth/device-flow.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACzD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAG7C,eAAO,MAAM,YAAY,iDAAiD,CAAC;AAI3E,iGAAiG;AACjG,qBAAa,uBAAuB;;gBAMtB,KAAK,EAAE;QACjB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;QAC3B,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,CAAC;QACvC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;KAC7B;IAOK,mBAAmB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAiDrE,sBAAsB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,IAAI;IAKnD,kBAAkB,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAqC9D,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;IAwB1D,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;CAwD9D"}
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { randomBytes } from 'node:crypto';
|
|
2
|
+
import { renderOAuthPage } from './branding.js';
|
|
3
|
+
import { hashToken, randomToken } from './tokens.js';
|
|
4
|
+
export const DEVICE_GRANT = 'urn:ietf:params:oauth:grant-type:device_code';
|
|
5
|
+
const DEVICE_TTL_SECONDS = 600;
|
|
6
|
+
const DEVICE_POLL_INTERVAL_SECONDS = 5;
|
|
7
|
+
/** RFC 8628 endpoints, backed by the existing authorization-code consent path in the browser. */
|
|
8
|
+
export class DeviceAuthorizationFlow {
|
|
9
|
+
#issuer;
|
|
10
|
+
#store;
|
|
11
|
+
#provider;
|
|
12
|
+
#nowSeconds;
|
|
13
|
+
constructor(input) {
|
|
14
|
+
this.#issuer = input.issuer.replace(/\/+$/, '');
|
|
15
|
+
this.#store = input.store;
|
|
16
|
+
this.#provider = input.provider;
|
|
17
|
+
this.#nowSeconds = input.now ?? (() => Math.floor(Date.now() / 1000));
|
|
18
|
+
}
|
|
19
|
+
async handleAuthorization(req, res) {
|
|
20
|
+
const body = formBody(req);
|
|
21
|
+
const clientId = stringField(body, 'client_id');
|
|
22
|
+
const resource = stringField(body, 'resource');
|
|
23
|
+
const scope = optionalStringField(body, 'scope');
|
|
24
|
+
if (clientId === undefined || resource === undefined || !this.#validResource(resource)) {
|
|
25
|
+
sendOAuthError(res, 'invalid_request');
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const client = await this.#store.getClient(clientId);
|
|
29
|
+
const callback = this.#callbackUrl();
|
|
30
|
+
if (client === undefined ||
|
|
31
|
+
client.token_endpoint_auth_method !== 'none' ||
|
|
32
|
+
!client.grant_types?.includes(DEVICE_GRANT) ||
|
|
33
|
+
!client.redirect_uris.includes(callback)) {
|
|
34
|
+
sendOAuthError(res, 'invalid_client', 401);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
const rawDeviceCode = randomToken();
|
|
38
|
+
const rawUserCode = userCode();
|
|
39
|
+
const now = this.#nowSeconds();
|
|
40
|
+
await this.#store.createDeviceAuthorization({
|
|
41
|
+
deviceCode: hashToken(rawDeviceCode),
|
|
42
|
+
userCode: hashToken(normalizeUserCode(rawUserCode)),
|
|
43
|
+
clientId,
|
|
44
|
+
resource: normalizeUrl(resource),
|
|
45
|
+
...(scope !== undefined ? { scope } : {}),
|
|
46
|
+
status: 'pending',
|
|
47
|
+
expiresAt: now + DEVICE_TTL_SECONDS,
|
|
48
|
+
nextPollAt: now,
|
|
49
|
+
intervalSeconds: DEVICE_POLL_INTERVAL_SECONDS,
|
|
50
|
+
});
|
|
51
|
+
const verificationUri = `${this.#issuer}/device`;
|
|
52
|
+
const complete = new URL(verificationUri);
|
|
53
|
+
complete.searchParams.set('user_code', rawUserCode);
|
|
54
|
+
res.setHeader('cache-control', 'no-store');
|
|
55
|
+
res.json({
|
|
56
|
+
device_code: rawDeviceCode,
|
|
57
|
+
user_code: rawUserCode,
|
|
58
|
+
verification_uri: verificationUri,
|
|
59
|
+
verification_uri_complete: complete.href,
|
|
60
|
+
expires_in: DEVICE_TTL_SECONDS,
|
|
61
|
+
interval: DEVICE_POLL_INTERVAL_SECONDS,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
handleVerificationPage(req, res) {
|
|
65
|
+
const code = typeof req.query.user_code === 'string' ? req.query.user_code : '';
|
|
66
|
+
res.status(200).type('html').send(renderDeviceCodePage(code));
|
|
67
|
+
}
|
|
68
|
+
async handleVerification(req, res) {
|
|
69
|
+
const rawUserCode = stringField(formBody(req), 'user_code');
|
|
70
|
+
const normalized = rawUserCode === undefined ? undefined : normalizeUserCode(rawUserCode);
|
|
71
|
+
const device = normalized === undefined
|
|
72
|
+
? undefined
|
|
73
|
+
: await this.#store.getDeviceAuthorizationByUserCode(hashToken(normalized));
|
|
74
|
+
if (device === undefined) {
|
|
75
|
+
res
|
|
76
|
+
.status(400)
|
|
77
|
+
.type('html')
|
|
78
|
+
.send(renderDeviceCodePage(rawUserCode ?? '', true));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const rawState = randomToken();
|
|
82
|
+
const challenge = randomToken();
|
|
83
|
+
await this.#store.createDeviceBrowserSession({
|
|
84
|
+
state: hashToken(rawState),
|
|
85
|
+
deviceCode: device.deviceCode,
|
|
86
|
+
clientId: device.clientId,
|
|
87
|
+
resource: device.resource,
|
|
88
|
+
codeChallenge: challenge,
|
|
89
|
+
expiresAt: device.expiresAt,
|
|
90
|
+
});
|
|
91
|
+
const authorize = new URL(`${this.#issuer}/authorize`);
|
|
92
|
+
authorize.searchParams.set('client_id', device.clientId);
|
|
93
|
+
authorize.searchParams.set('redirect_uri', this.#callbackUrl());
|
|
94
|
+
authorize.searchParams.set('response_type', 'code');
|
|
95
|
+
authorize.searchParams.set('code_challenge', challenge);
|
|
96
|
+
authorize.searchParams.set('code_challenge_method', 'S256');
|
|
97
|
+
authorize.searchParams.set('state', rawState);
|
|
98
|
+
authorize.searchParams.set('resource', device.resource);
|
|
99
|
+
if (device.scope !== undefined)
|
|
100
|
+
authorize.searchParams.set('scope', device.scope);
|
|
101
|
+
res.redirect(302, authorize.href);
|
|
102
|
+
}
|
|
103
|
+
async handleCallback(req, res) {
|
|
104
|
+
const rawState = typeof req.query.state === 'string' ? req.query.state : undefined;
|
|
105
|
+
const session = rawState === undefined
|
|
106
|
+
? undefined
|
|
107
|
+
: await this.#store.consumeDeviceBrowserSession(hashToken(rawState));
|
|
108
|
+
if (session === undefined) {
|
|
109
|
+
res.status(400).type('html').send(renderCompletionPage(false));
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (typeof req.query.error === 'string') {
|
|
113
|
+
await this.#store.denyDeviceAuthorization(session.deviceCode);
|
|
114
|
+
res.status(200).type('html').send(renderCompletionPage(false));
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
const code = typeof req.query.code === 'string' ? req.query.code : undefined;
|
|
118
|
+
const approved = code !== undefined && (await this.#provider.completeDeviceAuthorization(session, code));
|
|
119
|
+
res
|
|
120
|
+
.status(approved ? 200 : 400)
|
|
121
|
+
.type('html')
|
|
122
|
+
.send(renderCompletionPage(approved));
|
|
123
|
+
}
|
|
124
|
+
async handleToken(req, res) {
|
|
125
|
+
const body = formBody(req);
|
|
126
|
+
const clientId = stringField(body, 'client_id');
|
|
127
|
+
const rawDeviceCode = stringField(body, 'device_code');
|
|
128
|
+
const resource = optionalStringField(body, 'resource');
|
|
129
|
+
if (clientId === undefined || rawDeviceCode === undefined) {
|
|
130
|
+
sendOAuthError(res, 'invalid_request');
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const client = await this.#store.getClient(clientId);
|
|
134
|
+
if (client === undefined ||
|
|
135
|
+
client.token_endpoint_auth_method !== 'none' ||
|
|
136
|
+
!client.grant_types?.includes(DEVICE_GRANT)) {
|
|
137
|
+
sendOAuthError(res, 'invalid_client', 401);
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const result = await this.#store.pollDeviceAuthorization({
|
|
141
|
+
deviceCode: hashToken(rawDeviceCode),
|
|
142
|
+
clientId,
|
|
143
|
+
...(resource !== undefined ? { resource: normalizeUrl(resource) } : {}),
|
|
144
|
+
nowSeconds: this.#nowSeconds(),
|
|
145
|
+
});
|
|
146
|
+
if (result.status !== 'approved') {
|
|
147
|
+
sendOAuthError(res, result.status);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const tokens = await this.#provider.issueDeviceTokens(result.record);
|
|
151
|
+
if (!(await this.#store.completeDeviceTokenIssuance(result.record.deviceCode, result.record.clientId))) {
|
|
152
|
+
sendOAuthError(res, 'expired_token');
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
res.setHeader('cache-control', 'no-store');
|
|
156
|
+
res.json(tokens);
|
|
157
|
+
}
|
|
158
|
+
#callbackUrl() {
|
|
159
|
+
return `${this.#issuer}/oauth/device/callback`;
|
|
160
|
+
}
|
|
161
|
+
#validResource(resource) {
|
|
162
|
+
try {
|
|
163
|
+
const normalized = normalizeUrl(resource);
|
|
164
|
+
return (normalized === normalizeUrl(this.#issuer) || normalized === `${this.#issuer}/developer/cli`);
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
function formBody(req) {
|
|
172
|
+
return (req.body ?? {});
|
|
173
|
+
}
|
|
174
|
+
function stringField(body, name) {
|
|
175
|
+
const value = body[name];
|
|
176
|
+
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
177
|
+
}
|
|
178
|
+
function optionalStringField(body, name) {
|
|
179
|
+
return stringField(body, name);
|
|
180
|
+
}
|
|
181
|
+
function normalizeUrl(value) {
|
|
182
|
+
const url = new URL(value);
|
|
183
|
+
url.hash = '';
|
|
184
|
+
url.search = '';
|
|
185
|
+
return url.href;
|
|
186
|
+
}
|
|
187
|
+
function normalizeUserCode(value) {
|
|
188
|
+
return value.toUpperCase().replace(/[^A-Z2-9]/g, '');
|
|
189
|
+
}
|
|
190
|
+
function userCode() {
|
|
191
|
+
const alphabet = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789';
|
|
192
|
+
const bytes = randomBytes(8);
|
|
193
|
+
let value = '';
|
|
194
|
+
for (let index = 0; index < 8; index += 1) {
|
|
195
|
+
value += alphabet[(bytes[index] ?? 0) % alphabet.length];
|
|
196
|
+
}
|
|
197
|
+
return `${value.slice(0, 4)}-${value.slice(4)}`;
|
|
198
|
+
}
|
|
199
|
+
function sendOAuthError(res, error, status = 400) {
|
|
200
|
+
res.setHeader('cache-control', 'no-store');
|
|
201
|
+
res.status(status).json({ error });
|
|
202
|
+
}
|
|
203
|
+
function renderDeviceCodePage(code, invalid = false) {
|
|
204
|
+
return renderOAuthPage({
|
|
205
|
+
title: 'Sign in — Noodle Seed',
|
|
206
|
+
kicker: 'CLI sign in',
|
|
207
|
+
heading: 'Enter your device code',
|
|
208
|
+
contentHtml: `${invalid ? '<p class="ns-lede">That code is invalid or expired. Try the code again.</p>' : ''}${code === ''
|
|
209
|
+
? ''
|
|
210
|
+
: `<p class="ns-lede">Confirm <strong>${escapeHtml(code)}</strong> matches the code shown in your terminal.</p>`}<form method="post" action="/device">
|
|
211
|
+
<label for="user_code">Device code</label>
|
|
212
|
+
<input id="user_code" name="user_code" value="${escapeHtml(code)}" autocomplete="one-time-code" required />
|
|
213
|
+
<div class="btn-glow"><button class="btn btn-primary" type="submit">Continue</button></div>
|
|
214
|
+
</form>`,
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
function renderCompletionPage(approved) {
|
|
218
|
+
return renderOAuthPage({
|
|
219
|
+
title: `${approved ? 'Signed in' : 'Sign-in denied'} — Noodle Seed`,
|
|
220
|
+
kicker: approved ? 'Complete' : 'Not completed',
|
|
221
|
+
heading: approved ? 'You are signed in' : 'Sign-in was not completed',
|
|
222
|
+
contentHtml: approved
|
|
223
|
+
? '<p class="ns-lede">You can return to your terminal. This window can now be closed.</p>'
|
|
224
|
+
: '<p class="ns-lede">Return to your terminal and start sign-in again if you still want to continue.</p>',
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
function escapeHtml(value) {
|
|
228
|
+
return value.replace(/[&<>"']/g, (character) => {
|
|
229
|
+
const entities = {
|
|
230
|
+
'&': '&',
|
|
231
|
+
'<': '<',
|
|
232
|
+
'>': '>',
|
|
233
|
+
'"': '"',
|
|
234
|
+
"'": ''',
|
|
235
|
+
};
|
|
236
|
+
return entities[character] ?? character;
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=device-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-flow.js","sourceRoot":"","sources":["../../src/oauth/device-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { OAuthTokens } from '@modelcontextprotocol/sdk/shared/auth.js';
|
|
2
|
+
import type { DeviceAuthorizationRecord, DeviceBrowserSessionRecord } from './device-store.js';
|
|
3
|
+
import type { OAuthStore } from './store.js';
|
|
4
|
+
import type { OAuthTokenIssuer } from './token-issuer.js';
|
|
5
|
+
export declare function completeDeviceAuthorization(input: {
|
|
6
|
+
readonly store: OAuthStore;
|
|
7
|
+
readonly issuer: string;
|
|
8
|
+
readonly session: DeviceBrowserSessionRecord;
|
|
9
|
+
readonly authorizationCode: string;
|
|
10
|
+
}): Promise<boolean>;
|
|
11
|
+
export declare function issueDeviceTokens(input: {
|
|
12
|
+
readonly tokenIssuer: OAuthTokenIssuer;
|
|
13
|
+
readonly record: DeviceAuthorizationRecord;
|
|
14
|
+
}): Promise<OAuthTokens>;
|
|
15
|
+
//# sourceMappingURL=device-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-provider.d.ts","sourceRoot":"","sources":["../../src/oauth/device-provider.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0CAA0C,CAAC;AAC5E,OAAO,KAAK,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAE/F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAG1D,wBAAsB,2BAA2B,CAAC,KAAK,EAAE;IACvD,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,0BAA0B,CAAC;IAC7C,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;CACpC,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBnB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,yBAAyB,CAAC;CAC5C,GAAG,OAAO,CAAC,WAAW,CAAC,CAmBvB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { InvalidGrantError } from '@modelcontextprotocol/sdk/server/auth/errors.js';
|
|
2
|
+
import { storedOAuthOwnerPreferences } from './identity-preferences.js';
|
|
3
|
+
import { hashToken } from './tokens.js';
|
|
4
|
+
export async function completeDeviceAuthorization(input) {
|
|
5
|
+
const record = await input.store.redeemAuthorizationCode(hashToken(input.authorizationCode));
|
|
6
|
+
if (record === undefined ||
|
|
7
|
+
record.clientId !== input.session.clientId ||
|
|
8
|
+
record.redirectUri !== `${input.issuer.replace(/\/+$/, '')}/oauth/device/callback` ||
|
|
9
|
+
record.resource !== input.session.resource ||
|
|
10
|
+
record.codeChallenge !== input.session.codeChallenge) {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
return input.store.approveDeviceAuthorization(input.session.deviceCode, {
|
|
14
|
+
ownerSubject: record.ownerSubject,
|
|
15
|
+
...(record.ownerEmail !== undefined ? { ownerEmail: record.ownerEmail } : {}),
|
|
16
|
+
...storedOAuthOwnerPreferences({
|
|
17
|
+
locale: record.ownerLocale,
|
|
18
|
+
timeZone: record.ownerTimeZone,
|
|
19
|
+
}),
|
|
20
|
+
...(record.identityKind !== undefined ? { identityKind: record.identityKind } : {}),
|
|
21
|
+
...(record.identityProvider !== undefined ? { identityProvider: record.identityProvider } : {}),
|
|
22
|
+
...(record.developerGrantId !== undefined ? { developerGrantId: record.developerGrantId } : {}),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
export function issueDeviceTokens(input) {
|
|
26
|
+
const record = input.record;
|
|
27
|
+
if (record.ownerSubject === undefined) {
|
|
28
|
+
throw new InvalidGrantError('device authorization is missing an approved identity');
|
|
29
|
+
}
|
|
30
|
+
return input.tokenIssuer.issueTokens({
|
|
31
|
+
clientId: record.clientId,
|
|
32
|
+
ownerSubject: record.ownerSubject,
|
|
33
|
+
resource: record.resource,
|
|
34
|
+
...(record.ownerEmail !== undefined ? { ownerEmail: record.ownerEmail } : {}),
|
|
35
|
+
...storedOAuthOwnerPreferences({
|
|
36
|
+
locale: record.ownerLocale,
|
|
37
|
+
timeZone: record.ownerTimeZone,
|
|
38
|
+
}),
|
|
39
|
+
...(record.scope !== undefined ? { scope: record.scope } : {}),
|
|
40
|
+
...(record.identityKind !== undefined ? { identityKind: record.identityKind } : {}),
|
|
41
|
+
...(record.identityProvider !== undefined ? { identityProvider: record.identityProvider } : {}),
|
|
42
|
+
...(record.developerGrantId !== undefined ? { developerGrantId: record.developerGrantId } : {}),
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=device-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-provider.js","sourceRoot":"","sources":["../../src/oauth/device-provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-store-postgres-schema.d.ts","sourceRoot":"","sources":["../../src/oauth/device-store-postgres-schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAE/B,wBAAsB,+BAA+B,CAAC,IAAI,EAAE,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CA+B/E"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export async function ensureDeviceAuthorizationSchema(pool) {
|
|
2
|
+
await pool.query(`
|
|
3
|
+
CREATE TABLE IF NOT EXISTS oauth_device_authorizations (
|
|
4
|
+
device_code text PRIMARY KEY,
|
|
5
|
+
user_code text UNIQUE NOT NULL,
|
|
6
|
+
client_id text NOT NULL,
|
|
7
|
+
resource text NOT NULL,
|
|
8
|
+
scope text,
|
|
9
|
+
status text NOT NULL,
|
|
10
|
+
owner_subject text,
|
|
11
|
+
owner_email text,
|
|
12
|
+
owner_locale text,
|
|
13
|
+
owner_time_zone text,
|
|
14
|
+
identity_kind text,
|
|
15
|
+
identity_provider text,
|
|
16
|
+
developer_grant_id text,
|
|
17
|
+
expires_at timestamptz NOT NULL,
|
|
18
|
+
next_poll_at timestamptz NOT NULL,
|
|
19
|
+
interval_seconds integer NOT NULL
|
|
20
|
+
)
|
|
21
|
+
`);
|
|
22
|
+
await pool.query(`
|
|
23
|
+
CREATE TABLE IF NOT EXISTS oauth_device_browser_sessions (
|
|
24
|
+
state text PRIMARY KEY,
|
|
25
|
+
device_code text NOT NULL,
|
|
26
|
+
client_id text NOT NULL,
|
|
27
|
+
resource text NOT NULL,
|
|
28
|
+
code_challenge text NOT NULL,
|
|
29
|
+
expires_at timestamptz NOT NULL
|
|
30
|
+
)
|
|
31
|
+
`);
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=device-store-postgres-schema.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-store-postgres-schema.js","sourceRoot":"","sources":["../../src/oauth/device-store-postgres-schema.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,+BAA+B,CAAC,IAAU;IAC9D,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;GAmBhB,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,KAAK,CAAC;;;;;;;;;GAShB,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { DeviceAuthorizationRecord, DeviceBrowserSessionRecord } from './device-store.js';
|
|
2
|
+
export interface DeviceAuthorizationRow {
|
|
3
|
+
readonly device_code: string;
|
|
4
|
+
readonly user_code: string;
|
|
5
|
+
readonly client_id: string;
|
|
6
|
+
readonly resource: string;
|
|
7
|
+
readonly scope: string | null;
|
|
8
|
+
readonly status: 'pending' | 'approved' | 'denied';
|
|
9
|
+
readonly owner_subject: string | null;
|
|
10
|
+
readonly owner_email: string | null;
|
|
11
|
+
readonly owner_locale: string | null;
|
|
12
|
+
readonly owner_time_zone: string | null;
|
|
13
|
+
readonly identity_kind: 'platform' | 'customer' | null;
|
|
14
|
+
readonly identity_provider: string | null;
|
|
15
|
+
readonly developer_grant_id: string | null;
|
|
16
|
+
readonly expires_at: Date;
|
|
17
|
+
readonly next_poll_at: Date;
|
|
18
|
+
readonly interval_seconds: number;
|
|
19
|
+
}
|
|
20
|
+
export interface DeviceBrowserSessionRow {
|
|
21
|
+
readonly state: string;
|
|
22
|
+
readonly device_code: string;
|
|
23
|
+
readonly client_id: string;
|
|
24
|
+
readonly resource: string;
|
|
25
|
+
readonly code_challenge: string;
|
|
26
|
+
readonly expires_at: Date;
|
|
27
|
+
}
|
|
28
|
+
export declare function deviceRowToRecord(row: DeviceAuthorizationRow): DeviceAuthorizationRecord;
|
|
29
|
+
export declare function deviceBrowserRowToRecord(row: DeviceBrowserSessionRow): DeviceBrowserSessionRecord;
|
|
30
|
+
//# sourceMappingURL=device-store-postgres-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-store-postgres-types.d.ts","sourceRoot":"","sources":["../../src/oauth/device-store-postgres-types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAE/F,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,QAAQ,CAAC;IACnD,QAAQ,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,QAAQ,CAAC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IACxC,QAAQ,CAAC,aAAa,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAAC;IACvD,QAAQ,CAAC,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1C,QAAQ,CAAC,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;IAC1B,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC;IAC5B,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;CACnC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;CAC3B;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,sBAAsB,GAAG,yBAAyB,CAmBxF;AAED,wBAAgB,wBAAwB,CAAC,GAAG,EAAE,uBAAuB,GAAG,0BAA0B,CASjG"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export function deviceRowToRecord(row) {
|
|
2
|
+
return {
|
|
3
|
+
deviceCode: row.device_code,
|
|
4
|
+
userCode: row.user_code,
|
|
5
|
+
clientId: row.client_id,
|
|
6
|
+
resource: row.resource,
|
|
7
|
+
...(row.scope !== null ? { scope: row.scope } : {}),
|
|
8
|
+
status: row.status,
|
|
9
|
+
...(row.owner_subject !== null ? { ownerSubject: row.owner_subject } : {}),
|
|
10
|
+
...(row.owner_email !== null ? { ownerEmail: row.owner_email } : {}),
|
|
11
|
+
...(row.owner_locale !== null ? { ownerLocale: row.owner_locale } : {}),
|
|
12
|
+
...(row.owner_time_zone !== null ? { ownerTimeZone: row.owner_time_zone } : {}),
|
|
13
|
+
...(row.identity_kind !== null ? { identityKind: row.identity_kind } : {}),
|
|
14
|
+
...(row.identity_provider !== null ? { identityProvider: row.identity_provider } : {}),
|
|
15
|
+
...(row.developer_grant_id !== null ? { developerGrantId: row.developer_grant_id } : {}),
|
|
16
|
+
expiresAt: Math.floor(new Date(row.expires_at).getTime() / 1000),
|
|
17
|
+
nextPollAt: Math.floor(new Date(row.next_poll_at).getTime() / 1000),
|
|
18
|
+
intervalSeconds: row.interval_seconds,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function deviceBrowserRowToRecord(row) {
|
|
22
|
+
return {
|
|
23
|
+
state: row.state,
|
|
24
|
+
deviceCode: row.device_code,
|
|
25
|
+
clientId: row.client_id,
|
|
26
|
+
resource: row.resource,
|
|
27
|
+
codeChallenge: row.code_challenge,
|
|
28
|
+
expiresAt: Math.floor(new Date(row.expires_at).getTime() / 1000),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=device-store-postgres-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-store-postgres-types.js","sourceRoot":"","sources":["../../src/oauth/device-store-postgres-types.ts"],"names":[],"mappings":"AA8BA,MAAM,UAAU,iBAAiB,CAAC,GAA2B;IAC3D,OAAO;QACL,UAAU,EAAE,GAAG,CAAC,WAAW;QAC3B,QAAQ,EAAE,GAAG,CAAC,SAAS;QACvB,QAAQ,EAAE,GAAG,CAAC,SAAS;QACvB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,GAAG,CAAC,GAAG,CAAC,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,GAAG,CAAC,GAAG,CAAC,WAAW,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACpE,GAAG,CAAC,GAAG,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvE,GAAG,CAAC,GAAG,CAAC,eAAe,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,GAAG,CAAC,GAAG,CAAC,aAAa,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1E,GAAG,CAAC,GAAG,CAAC,iBAAiB,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,GAAG,CAAC,iBAAiB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACtF,GAAG,CAAC,GAAG,CAAC,kBAAkB,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,GAAG,CAAC,kBAAkB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACxF,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;QAChE,UAAU,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;QACnE,eAAe,EAAE,GAAG,CAAC,gBAAgB;KACtC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,GAA4B;IACnE,OAAO;QACL,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,UAAU,EAAE,GAAG,CAAC,WAAW;QAC3B,QAAQ,EAAE,GAAG,CAAC,SAAS;QACvB,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,aAAa,EAAE,GAAG,CAAC,cAAc;QACjC,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;KACjE,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/** RFC 8628 state stored by the authorization server. All codes are stored as hashes. */
|
|
2
|
+
export interface DeviceAuthorizationRecord {
|
|
3
|
+
readonly deviceCode: string;
|
|
4
|
+
readonly userCode: string;
|
|
5
|
+
readonly clientId: string;
|
|
6
|
+
readonly resource: string;
|
|
7
|
+
readonly scope?: string;
|
|
8
|
+
readonly status: 'pending' | 'approved' | 'denied';
|
|
9
|
+
readonly ownerSubject?: string;
|
|
10
|
+
readonly ownerEmail?: string;
|
|
11
|
+
readonly ownerLocale?: string;
|
|
12
|
+
readonly ownerTimeZone?: string;
|
|
13
|
+
readonly identityKind?: 'platform' | 'customer';
|
|
14
|
+
readonly identityProvider?: string;
|
|
15
|
+
readonly developerGrantId?: string;
|
|
16
|
+
readonly expiresAt: number;
|
|
17
|
+
readonly nextPollAt: number;
|
|
18
|
+
readonly intervalSeconds: number;
|
|
19
|
+
}
|
|
20
|
+
export interface DeviceBrowserSessionRecord {
|
|
21
|
+
readonly state: string;
|
|
22
|
+
readonly deviceCode: string;
|
|
23
|
+
readonly clientId: string;
|
|
24
|
+
readonly resource: string;
|
|
25
|
+
readonly codeChallenge: string;
|
|
26
|
+
readonly expiresAt: number;
|
|
27
|
+
}
|
|
28
|
+
export interface DeviceAuthorizationIdentity {
|
|
29
|
+
readonly ownerSubject: string;
|
|
30
|
+
readonly ownerEmail?: string;
|
|
31
|
+
readonly ownerLocale?: string;
|
|
32
|
+
readonly ownerTimeZone?: string;
|
|
33
|
+
readonly identityKind?: 'platform' | 'customer';
|
|
34
|
+
readonly identityProvider?: string;
|
|
35
|
+
readonly developerGrantId?: string;
|
|
36
|
+
}
|
|
37
|
+
export type DeviceAuthorizationPoll = {
|
|
38
|
+
readonly status: 'authorization_pending';
|
|
39
|
+
} | {
|
|
40
|
+
readonly status: 'slow_down';
|
|
41
|
+
} | {
|
|
42
|
+
readonly status: 'access_denied';
|
|
43
|
+
} | {
|
|
44
|
+
readonly status: 'expired_token';
|
|
45
|
+
} | {
|
|
46
|
+
readonly status: 'invalid_grant';
|
|
47
|
+
} | {
|
|
48
|
+
readonly status: 'approved';
|
|
49
|
+
readonly record: DeviceAuthorizationRecord;
|
|
50
|
+
};
|
|
51
|
+
export interface DeviceAuthorizationStore {
|
|
52
|
+
createDeviceAuthorization(record: DeviceAuthorizationRecord): Promise<void>;
|
|
53
|
+
getDeviceAuthorizationByUserCode(userCode: string): Promise<DeviceAuthorizationRecord | undefined>;
|
|
54
|
+
createDeviceBrowserSession(record: DeviceBrowserSessionRecord): Promise<void>;
|
|
55
|
+
consumeDeviceBrowserSession(state: string): Promise<DeviceBrowserSessionRecord | undefined>;
|
|
56
|
+
approveDeviceAuthorization(deviceCode: string, identity: DeviceAuthorizationIdentity): Promise<boolean>;
|
|
57
|
+
denyDeviceAuthorization(deviceCode: string): Promise<boolean>;
|
|
58
|
+
pollDeviceAuthorization(input: {
|
|
59
|
+
readonly deviceCode: string;
|
|
60
|
+
readonly clientId: string;
|
|
61
|
+
readonly resource?: string;
|
|
62
|
+
readonly nowSeconds: number;
|
|
63
|
+
}): Promise<DeviceAuthorizationPoll>;
|
|
64
|
+
completeDeviceTokenIssuance(deviceCode: string, clientId: string): Promise<boolean>;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=device-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-store.d.ts","sourceRoot":"","sources":["../../src/oauth/device-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"device-store.js","sourceRoot":"","sources":["../../src/oauth/device-store.ts"],"names":[],"mappings":""}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/oauth/paths.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/oauth/paths.ts"],"names":[],"mappings":"AAuBA,2GAA2G;AAC3G,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAE1D"}
|
|
@@ -5,10 +5,13 @@
|
|
|
5
5
|
*/
|
|
6
6
|
const AUTH_SERVER_PATHS = new Set([
|
|
7
7
|
'/authorize',
|
|
8
|
+
'/device_authorization',
|
|
9
|
+
'/device',
|
|
8
10
|
'/token',
|
|
9
11
|
'/revoke',
|
|
10
12
|
'/register',
|
|
11
13
|
'/oauth/google/callback',
|
|
14
|
+
'/oauth/device/callback',
|
|
12
15
|
'/oauth/consent',
|
|
13
16
|
'/oauth/developer-grant',
|
|
14
17
|
'/oauth/customer/firebase/authorize',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/oauth/paths.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,iBAAiB,GAAwB,IAAI,GAAG,CAAC;IACrD,YAAY;IACZ,QAAQ;IACR,SAAS;IACT,WAAW;IACX,wBAAwB;IACxB,gBAAgB;IAChB,wBAAwB;IACxB,oCAAoC;IACpC,mCAAmC;IACnC,oCAAoC;IACpC,yCAAyC;IACzC,wBAAwB;CACzB,CAAC,CAAC;AAEH,2GAA2G;AAC3G,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,OAAO,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACzC,CAAC"}
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/oauth/paths.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,iBAAiB,GAAwB,IAAI,GAAG,CAAC;IACrD,YAAY;IACZ,uBAAuB;IACvB,SAAS;IACT,QAAQ;IACR,SAAS;IACT,WAAW;IACX,wBAAwB;IACxB,wBAAwB;IACxB,gBAAgB;IAChB,wBAAwB;IACxB,oCAAoC;IACpC,mCAAmC;IACnC,oCAAoC;IACpC,yCAAyC;IACzC,wBAAwB;CACzB,CAAC,CAAC;AAEH,2GAA2G;AAC3G,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,OAAO,iBAAiB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -8,6 +8,8 @@ import type { Request, Response } from 'express';
|
|
|
8
8
|
import type { SignupAuthorizer } from '../auth/deploy-gate.js';
|
|
9
9
|
import type { SecretEnvelope, TenantBridgeAuthConfig } from '../store.js';
|
|
10
10
|
import type { DeveloperGrantAuthorizer } from './developer-grant-authorizer.js';
|
|
11
|
+
import { DeviceAuthorizationFlow } from './device-flow.js';
|
|
12
|
+
import type { DeviceAuthorizationRecord, DeviceBrowserSessionRecord } from './device-store.js';
|
|
11
13
|
import type { GoogleAuthenticator } from './google.js';
|
|
12
14
|
import type { OAuthStore } from './store.js';
|
|
13
15
|
export interface NoodleOAuthProviderConfig {
|
|
@@ -47,12 +49,17 @@ export declare class NoodleOAuthProvider implements OAuthServerProvider {
|
|
|
47
49
|
#private;
|
|
48
50
|
constructor(config: NoodleOAuthProviderConfig);
|
|
49
51
|
get clientsStore(): OAuthRegisteredClientsStore;
|
|
52
|
+
get deviceAuthorizationFlow(): DeviceAuthorizationFlow;
|
|
50
53
|
/** Begin authorization: persist the pending request and redirect the user to "Sign in with Google". */
|
|
51
54
|
authorize(client: OAuthClientInformationFull, params: AuthorizationParams, res: Response): Promise<void>;
|
|
52
55
|
/** Return the stored PKCE challenge for a code (non-destructive — the SDK validates the verifier against it). */
|
|
53
56
|
challengeForAuthorizationCode(client: OAuthClientInformationFull, authorizationCode: string): Promise<string>;
|
|
54
57
|
/** Redeem an authorization code (single-use) and mint the owner's tokens. PKCE was validated by the SDK. */
|
|
55
58
|
exchangeAuthorizationCode(client: OAuthClientInformationFull, authorizationCode: string, _codeVerifier?: string, redirectUri?: string, resource?: URL): Promise<OAuthTokens>;
|
|
59
|
+
/** Complete the server-owned authorization-code bridge used by the RFC 8628 verification page. */
|
|
60
|
+
completeDeviceAuthorization(session: DeviceBrowserSessionRecord, authorizationCode: string): Promise<boolean>;
|
|
61
|
+
/** Mint normal access/refresh tokens after the device authorization has been approved and consumed. */
|
|
62
|
+
issueDeviceTokens(record: DeviceAuthorizationRecord): Promise<OAuthTokens>;
|
|
56
63
|
/** Rotate a refresh token with grace/recovery handling for concurrent or retried refreshes. */
|
|
57
64
|
exchangeRefreshToken(client: OAuthClientInformationFull, refreshToken: string, _scopes?: string[], resource?: URL): Promise<OAuthTokens>;
|
|
58
65
|
/** Verify an access token (issuer/signature/expiry). Provided for interface completeness — the data-plane
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/oauth/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,kDAAkD,CAAC;AAMpG,OAAO,KAAK,EACV,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,mDAAmD,CAAC;AAE3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gDAAgD,CAAC;AAC/E,OAAO,KAAK,EACV,0BAA0B,EAC1B,2BAA2B,EAC3B,WAAW,EACZ,MAAM,0CAA0C,CAAC;AAClD,OAAO,EAEL,KAAK,kBAAkB,EAEvB,KAAK,gBAAgB,EACtB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,KAAK,MAAM,EAAc,MAAM,6BAA6B,CAAC;AACtE,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAU1E,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAEhF,OAAO,KAAK,EAAE,mBAAmB,EAAkB,MAAM,aAAa,CAAC;AAkBvE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/oauth/provider.ts"],"names":[],"mappings":"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"}
|