@rpcbase/auth 0.91.0 → 0.93.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/oauth/index.js +86 -28
- package/dist/oauth/index.js.map +1 -1
- package/dist/oauth/lib.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -20,7 +20,7 @@ export const runApi = async ({ app }) => {
|
|
|
20
20
|
}
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
The OAuth request (`state` + PKCE verifier) is stored server-side in `RBOAuthRequest` (global model). A short-lived HttpOnly cookie binds `state` to the initiating browser (SameSite=None; Secure on HTTPS). The callback handler uses an Express session only to sign the user in.
|
|
24
24
|
|
|
25
25
|
### 2) Configure providers
|
|
26
26
|
|
package/dist/oauth/index.js
CHANGED
|
@@ -131,11 +131,30 @@ const isSafeOAuthProviderId = (value) => {
|
|
|
131
131
|
if (RESERVED_KEYS.has(providerId)) return false;
|
|
132
132
|
return /^[a-zA-Z0-9_-]+$/.test(providerId);
|
|
133
133
|
};
|
|
134
|
+
const OAUTH_REQUEST_TTL_MS = 10 * 60 * 1e3;
|
|
135
|
+
const OAUTH_STATE_COOKIE_NAME = "rb_oauth_state";
|
|
134
136
|
const getQueryString = (value) => {
|
|
135
137
|
if (typeof value === "string") return value;
|
|
136
138
|
if (Array.isArray(value) && typeof value[0] === "string") return value[0];
|
|
137
139
|
return null;
|
|
138
140
|
};
|
|
141
|
+
const getCookieValue = (ctx, name) => {
|
|
142
|
+
const header = ctx.req.headers?.cookie;
|
|
143
|
+
if (typeof header !== "string" || !header) return null;
|
|
144
|
+
for (const part of header.split(";")) {
|
|
145
|
+
const [rawKey, ...rest] = part.split("=");
|
|
146
|
+
const key = rawKey?.trim();
|
|
147
|
+
if (!key || key !== name) continue;
|
|
148
|
+
const rawValue = rest.join("=").trim();
|
|
149
|
+
if (!rawValue) return "";
|
|
150
|
+
try {
|
|
151
|
+
return decodeURIComponent(rawValue);
|
|
152
|
+
} catch {
|
|
153
|
+
return rawValue;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
return null;
|
|
157
|
+
};
|
|
139
158
|
const isSafeRedirectPath = (candidate) => {
|
|
140
159
|
if (!candidate.startsWith("/")) return false;
|
|
141
160
|
if (candidate.startsWith("//")) return false;
|
|
@@ -210,33 +229,46 @@ const getOAuthStartRedirectUrl = async ({
|
|
|
210
229
|
if (!provider) {
|
|
211
230
|
return { success: false, error: "unknown_provider", statusCode: 404 };
|
|
212
231
|
}
|
|
213
|
-
if (!ctx.req.session) {
|
|
214
|
-
return { success: false, error: "session_unavailable", statusCode: 500 };
|
|
215
|
-
}
|
|
216
232
|
const origin = getRequestOrigin(ctx);
|
|
217
233
|
if (!origin) {
|
|
218
234
|
return { success: false, error: "origin_unavailable", statusCode: 500 };
|
|
219
235
|
}
|
|
236
|
+
const isHttps = origin.startsWith("https://");
|
|
220
237
|
const callbackPath = resolveCallbackPath(provider.callbackPath);
|
|
221
238
|
if (!callbackPath) {
|
|
222
239
|
return { success: false, error: "invalid_callback_path", statusCode: 500 };
|
|
223
240
|
}
|
|
224
241
|
const state = crypto.randomBytes(16).toString("hex");
|
|
225
242
|
const { verifier, challenge } = generatePkcePair();
|
|
226
|
-
const sessionAny = ctx.req.session;
|
|
227
|
-
const rbOauthRaw = sessionAny.rbOauth;
|
|
228
|
-
if (!rbOauthRaw || typeof rbOauthRaw !== "object" || Array.isArray(rbOauthRaw)) {
|
|
229
|
-
sessionAny.rbOauth = /* @__PURE__ */ Object.create(null);
|
|
230
|
-
} else if (Object.getPrototypeOf(rbOauthRaw) !== null) {
|
|
231
|
-
sessionAny.rbOauth = Object.assign(/* @__PURE__ */ Object.create(null), rbOauthRaw);
|
|
232
|
-
}
|
|
233
243
|
const safeReturnTo = typeof returnTo === "string" && isSafeRedirectPath(returnTo) ? returnTo : void 0;
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
244
|
+
try {
|
|
245
|
+
const OAuthRequest = await models.getGlobal("RBOAuthRequest", ctx);
|
|
246
|
+
const now = /* @__PURE__ */ new Date();
|
|
247
|
+
await OAuthRequest.create({
|
|
248
|
+
_id: state,
|
|
249
|
+
providerId,
|
|
250
|
+
codeVerifier: verifier,
|
|
251
|
+
returnTo: safeReturnTo,
|
|
252
|
+
createdAt: now,
|
|
253
|
+
expiresAt: new Date(now.getTime() + OAUTH_REQUEST_TTL_MS)
|
|
254
|
+
});
|
|
255
|
+
} catch (err) {
|
|
256
|
+
console.warn("oauth::failed_to_store_request", err);
|
|
257
|
+
return { success: false, error: "oauth_request_store_failed", statusCode: 500 };
|
|
258
|
+
}
|
|
259
|
+
try {
|
|
260
|
+
;
|
|
261
|
+
ctx.res.cookie(OAUTH_STATE_COOKIE_NAME, `${providerId}:${state}`, {
|
|
262
|
+
httpOnly: true,
|
|
263
|
+
secure: isHttps,
|
|
264
|
+
sameSite: isHttps ? "none" : "lax",
|
|
265
|
+
path: callbackPath,
|
|
266
|
+
maxAge: OAUTH_REQUEST_TTL_MS
|
|
267
|
+
});
|
|
268
|
+
} catch (err) {
|
|
269
|
+
console.warn("oauth::failed_to_set_state_cookie", err);
|
|
270
|
+
return { success: false, error: "oauth_cookie_set_failed", statusCode: 500 };
|
|
271
|
+
}
|
|
240
272
|
const oidc = await getOidcWellKnown(provider.issuer);
|
|
241
273
|
const redirectUri = `${origin}${callbackPath}`;
|
|
242
274
|
const url = new URL(oidc.authorization_endpoint);
|
|
@@ -274,13 +306,11 @@ const processOAuthCallback = async ({
|
|
|
274
306
|
if (!provider) {
|
|
275
307
|
return { success: false, type: "error", error: "unknown_provider", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=unknown_provider` };
|
|
276
308
|
}
|
|
277
|
-
if (!ctx.req.session) {
|
|
278
|
-
return { success: false, type: "error", error: "session_unavailable", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=session_unavailable` };
|
|
279
|
-
}
|
|
280
309
|
const origin = getRequestOrigin(ctx);
|
|
281
310
|
if (!origin) {
|
|
282
311
|
return { success: false, type: "error", error: "origin_unavailable", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=origin_unavailable` };
|
|
283
312
|
}
|
|
313
|
+
const isHttps = origin.startsWith("https://");
|
|
284
314
|
const callbackPath = resolveCallbackPath(provider.callbackPath);
|
|
285
315
|
if (!callbackPath) {
|
|
286
316
|
return { success: false, type: "error", error: "invalid_callback_path", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_callback_path` };
|
|
@@ -289,23 +319,30 @@ const processOAuthCallback = async ({
|
|
|
289
319
|
const code = (getQueryString(bodyParams?.code) ?? getQueryString(ctx.req.query?.code))?.trim() ?? "";
|
|
290
320
|
const state = (getQueryString(bodyParams?.state) ?? getQueryString(ctx.req.query?.state))?.trim() ?? "";
|
|
291
321
|
const oauthUserRaw = (getQueryString(bodyParams?.user) ?? getQueryString(ctx.req.query?.user))?.trim() ?? "";
|
|
292
|
-
const sessionAny = ctx.req.session;
|
|
293
|
-
const sessionState = sessionAny.rbOauth?.[providerId];
|
|
294
|
-
const returnTo = typeof sessionState?.returnTo === "string" ? sessionState.returnTo : void 0;
|
|
295
322
|
if (!code || !state) {
|
|
296
323
|
return { success: false, type: "error", error: "missing_code_or_state", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_code_or_state` };
|
|
297
324
|
}
|
|
298
|
-
|
|
325
|
+
const stateCookieValue = getCookieValue(ctx, OAUTH_STATE_COOKIE_NAME);
|
|
326
|
+
if (stateCookieValue !== `${providerId}:${state}`) {
|
|
327
|
+
return { success: false, type: "error", error: "invalid_state", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_state` };
|
|
328
|
+
}
|
|
329
|
+
let oauthRequest = null;
|
|
330
|
+
let OAuthRequestModel = null;
|
|
331
|
+
try {
|
|
332
|
+
OAuthRequestModel = await models.getGlobal("RBOAuthRequest", ctx);
|
|
333
|
+
oauthRequest = await OAuthRequestModel.findOne({ _id: state, providerId }).lean();
|
|
334
|
+
} catch (err) {
|
|
335
|
+
console.warn("oauth::failed_to_load_request", err);
|
|
336
|
+
return { success: false, type: "error", error: "oauth_request_load_failed", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=oauth_request_load_failed` };
|
|
337
|
+
}
|
|
338
|
+
if (!oauthRequest) {
|
|
299
339
|
return { success: false, type: "error", error: "invalid_state", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_state` };
|
|
300
340
|
}
|
|
301
|
-
const
|
|
341
|
+
const returnTo = typeof oauthRequest.returnTo === "string" ? oauthRequest.returnTo : void 0;
|
|
342
|
+
const codeVerifier = typeof oauthRequest.codeVerifier === "string" ? oauthRequest.codeVerifier : "";
|
|
302
343
|
if (!codeVerifier) {
|
|
303
344
|
return { success: false, type: "error", error: "missing_code_verifier", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_code_verifier` };
|
|
304
345
|
}
|
|
305
|
-
delete sessionAny.rbOauth?.[providerId];
|
|
306
|
-
if (sessionAny.rbOauth && Object.keys(sessionAny.rbOauth).length === 0) {
|
|
307
|
-
delete sessionAny.rbOauth;
|
|
308
|
-
}
|
|
309
346
|
const oidc = await getOidcWellKnown(provider.issuer);
|
|
310
347
|
const redirectUri = `${origin}${callbackPath}`;
|
|
311
348
|
const tokenBody = new URLSearchParams();
|
|
@@ -402,6 +439,9 @@ const processOAuthCallback = async ({
|
|
|
402
439
|
}
|
|
403
440
|
return result;
|
|
404
441
|
}
|
|
442
|
+
if (!ctx.req.session) {
|
|
443
|
+
return { success: false, type: "error", error: "session_unavailable", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=session_unavailable` };
|
|
444
|
+
}
|
|
405
445
|
const now = /* @__PURE__ */ new Date();
|
|
406
446
|
let providerCreatedAt;
|
|
407
447
|
const oauthProvidersValue = user ? user.oauthProviders : void 0;
|
|
@@ -473,6 +513,24 @@ const processOAuthCallback = async ({
|
|
|
473
513
|
isEntryGateAuthorized: true,
|
|
474
514
|
tenantRoles
|
|
475
515
|
};
|
|
516
|
+
try {
|
|
517
|
+
if (OAuthRequestModel) {
|
|
518
|
+
await OAuthRequestModel.deleteOne({ _id: state, providerId });
|
|
519
|
+
}
|
|
520
|
+
} catch (err) {
|
|
521
|
+
console.warn("oauth::failed_to_delete_request", err);
|
|
522
|
+
}
|
|
523
|
+
try {
|
|
524
|
+
;
|
|
525
|
+
ctx.res.clearCookie(OAUTH_STATE_COOKIE_NAME, {
|
|
526
|
+
httpOnly: true,
|
|
527
|
+
secure: isHttps,
|
|
528
|
+
sameSite: isHttps ? "none" : "lax",
|
|
529
|
+
path: callbackPath
|
|
530
|
+
});
|
|
531
|
+
} catch (err) {
|
|
532
|
+
console.warn("oauth::failed_to_clear_state_cookie", err);
|
|
533
|
+
}
|
|
476
534
|
const redirectPath = returnTo && isSafeRedirectPath(returnTo) ? returnTo : successRedirectPath && isSafeRedirectPath(successRedirectPath) ? successRedirectPath : OAUTH_SUCCESS_REDIRECT_PATH;
|
|
477
535
|
return {
|
|
478
536
|
success: true,
|
package/dist/oauth/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/oauth/config.ts","../../src/oauth/jwt.ts","../../src/oauth/oidc.ts","../../src/oauth/pkce.ts","../../src/oauth/providerId.ts","../../src/oauth/lib.ts"],"sourcesContent":["export type OAuthProviderConfig = {\n issuer: string\n clientId: string\n clientSecret?: string\n scope: string\n callbackPath: string\n}\n\ntype OAuthProvidersConfig = Record<string, OAuthProviderConfig>\n\ntype OAuthProvidersStore = {\n providers: OAuthProvidersConfig\n}\n\nconst STORE_KEY = Symbol.for(\"@rpcbase/auth/oauthProviders\")\n\nconst getStore = (): OAuthProvidersStore => {\n const anyGlobal = globalThis as unknown as Record<string | symbol, unknown>\n const existing = anyGlobal[STORE_KEY] as OAuthProvidersStore | undefined\n if (existing && typeof existing === \"object\" && existing.providers && typeof existing.providers === \"object\") {\n return existing\n }\n\n const created: OAuthProvidersStore = { providers: {} }\n anyGlobal[STORE_KEY] = created\n return created\n}\n\nconst normalizeProviders = (providers: Record<string, OAuthProviderConfig>): OAuthProvidersConfig => {\n const result: OAuthProvidersConfig = {}\n\n const isSafeRedirectPath = (candidate: string) => {\n if (!candidate.startsWith(\"/\")) return false\n if (candidate.startsWith(\"//\")) return false\n return true\n }\n\n for (const [providerIdRaw, value] of Object.entries(providers)) {\n const providerId = providerIdRaw.trim()\n if (!providerId) continue\n\n const issuer = typeof value?.issuer === \"string\" ? value.issuer.trim() : \"\"\n const clientId = typeof value?.clientId === \"string\" ? value.clientId.trim() : \"\"\n if (!issuer) throw new Error(`oauth provider \"${providerId}\" missing issuer`)\n if (!clientId) throw new Error(`oauth provider \"${providerId}\" missing clientId`)\n\n const clientSecret = typeof value?.clientSecret === \"string\" && value.clientSecret.trim()\n ? value.clientSecret\n : undefined\n\n const scope = typeof value?.scope === \"string\" ? value.scope.trim() : \"\"\n if (!scope) throw new Error(`oauth provider \"${providerId}\" missing scope`)\n\n const callbackPath = typeof value?.callbackPath === \"string\"\n ? value.callbackPath.trim()\n : \"\"\n if (!callbackPath) throw new Error(`oauth provider \"${providerId}\" missing callbackPath`)\n if (!isSafeRedirectPath(callbackPath)) throw new Error(`oauth provider \"${providerId}\" has invalid callbackPath`)\n\n result[providerId] = {\n issuer,\n clientId,\n clientSecret,\n scope,\n callbackPath,\n }\n }\n\n return result\n}\n\nexport const configureOAuthProviders = (providers: Record<string, OAuthProviderConfig>) => {\n const store = getStore()\n const normalized = normalizeProviders(providers)\n store.providers = { ...store.providers, ...normalized }\n}\n\nexport const setOAuthProviders = (providers: Record<string, OAuthProviderConfig>) => {\n const store = getStore()\n store.providers = normalizeProviders(providers)\n}\n\nexport const getOAuthProviderConfig = (providerId: string): OAuthProviderConfig | null => {\n const store = getStore()\n return store.providers[providerId] ?? null\n}\n","const decodeBase64Url = (value: string) => {\n const padded = value.replace(/-/g, \"+\").replace(/_/g, \"/\") + \"===\".slice((value.length + 3) % 4)\n return Buffer.from(padded, \"base64\").toString(\"utf8\")\n}\n\nexport const decodeJwtPayload = <T = Record<string, unknown>>(token: string): T | null => {\n const parts = token.split(\".\")\n if (parts.length < 2) return null\n\n try {\n const json = decodeBase64Url(parts[1])\n const parsed = JSON.parse(json) as T\n if (!parsed || typeof parsed !== \"object\") return null\n return parsed\n } catch {\n return null\n }\n}\n\n","export type OidcWellKnown = {\n issuer: string\n authorization_endpoint: string\n token_endpoint: string\n userinfo_endpoint?: string\n jwks_uri?: string\n}\n\nconst cache = new Map<string, Promise<OidcWellKnown>>()\n\nconst normalizeIssuer = (raw: string) => raw.trim().replace(/\\/+$/, \"\")\n\nexport const getOidcWellKnown = async (issuerRaw: string): Promise<OidcWellKnown> => {\n const issuer = normalizeIssuer(issuerRaw)\n if (!issuer) {\n throw new Error(\"OIDC issuer is required\")\n }\n\n const existing = cache.get(issuer)\n if (existing) {\n return existing\n }\n\n const loader = (async () => {\n const url = new URL(\"/.well-known/openid-configuration\", issuer)\n const response = await fetch(url, { headers: { Accept: \"application/json\" } })\n if (!response.ok) {\n const body = await response.text().catch(() => \"\")\n throw new Error(`Failed to fetch OIDC discovery document: ${response.status} ${body}`)\n }\n\n const json = await response.json().catch(() => null) as Partial<OidcWellKnown> | null\n if (!json || typeof json !== \"object\") {\n throw new Error(\"Invalid OIDC discovery document\")\n }\n\n const authorizationEndpoint = typeof json.authorization_endpoint === \"string\"\n ? json.authorization_endpoint\n : \"\"\n const tokenEndpoint = typeof json.token_endpoint === \"string\"\n ? json.token_endpoint\n : \"\"\n const issuerValue = typeof json.issuer === \"string\" ? json.issuer : issuer\n const userinfoEndpoint = typeof json.userinfo_endpoint === \"string\" ? json.userinfo_endpoint : undefined\n const jwksUri = typeof json.jwks_uri === \"string\" ? json.jwks_uri : undefined\n\n if (!authorizationEndpoint || !tokenEndpoint) {\n throw new Error(\"OIDC discovery document missing required endpoints\")\n }\n\n return {\n issuer: issuerValue,\n authorization_endpoint: authorizationEndpoint,\n token_endpoint: tokenEndpoint,\n userinfo_endpoint: userinfoEndpoint,\n jwks_uri: jwksUri,\n } satisfies OidcWellKnown\n })()\n\n cache.set(issuer, loader)\n\n try {\n return await loader\n } catch (err) {\n cache.delete(issuer)\n throw err\n }\n}\n\n","import crypto from \"crypto\"\n\n\nexport const base64UrlEncode = (input: Buffer) => input\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/g, \"\")\n\nexport const generatePkcePair = () => {\n const verifier = base64UrlEncode(crypto.randomBytes(32))\n const challenge = base64UrlEncode(crypto.createHash(\"sha256\").update(verifier).digest())\n\n return { verifier, challenge }\n}\n\n","const RESERVED_KEYS = new Set([\"__proto__\", \"prototype\", \"constructor\"])\n\nexport const isSafeOAuthProviderId = (value: string) => {\n const providerId = value.trim()\n if (!providerId) return false\n if (providerId.length > 128) return false\n if (RESERVED_KEYS.has(providerId)) return false\n return /^[a-zA-Z0-9_-]+$/.test(providerId)\n}\n\n","import crypto from \"crypto\"\n\nimport { ApiHandler, Ctx } from \"@rpcbase/api\"\nimport { models } from \"@rpcbase/db\"\nimport { hashPasswordForStorage } from \"@rpcbase/server\"\n\nimport { getOAuthProviderConfig } from \"./config\"\nimport { decodeJwtPayload } from \"./jwt\"\nimport { getOidcWellKnown } from \"./oidc\"\nimport { generatePkcePair } from \"./pkce\"\nimport { isSafeOAuthProviderId } from \"./providerId\"\n\n\nconst getQueryString = (value: unknown) => {\n if (typeof value === \"string\") return value\n if (Array.isArray(value) && typeof value[0] === \"string\") return value[0]\n return null\n}\n\nconst isSafeRedirectPath = (candidate: string) => {\n if (!candidate.startsWith(\"/\")) return false\n if (candidate.startsWith(\"//\")) return false\n return true\n}\n\nconst getRequestOrigin = (ctx: Ctx<any>) => {\n const protoHeader = ctx.req.headers[\"x-forwarded-proto\"]\n const hostHeader = ctx.req.headers[\"x-forwarded-host\"]\n\n const protocol = typeof protoHeader === \"string\"\n ? protoHeader.split(\",\")[0].trim()\n : ctx.req.protocol\n\n const host = typeof hostHeader === \"string\"\n ? hostHeader.split(\",\")[0].trim()\n : ctx.req.get(\"host\")\n\n return protocol && host ? `${protocol}://${host}` : \"\"\n}\n\nconst resolveCallbackPath = (callbackPath: string) => {\n const trimmed = callbackPath.trim()\n return trimmed && isSafeRedirectPath(trimmed) ? trimmed : null\n}\n\nconst readTextBody = async (req: { on: (event: string, cb: (arg: any) => void) => void; setEncoding?: (enc: string) => void }) =>\n await new Promise<string>((resolve, reject) => {\n let body = \"\"\n if (typeof req.setEncoding === \"function\") {\n req.setEncoding(\"utf8\")\n }\n\n req.on(\"data\", (chunk: string) => {\n body += chunk\n if (body.length > 32_768) {\n reject(new Error(\"request_body_too_large\"))\n }\n })\n req.on(\"end\", () => resolve(body))\n req.on(\"error\", reject)\n })\n\nconst getFormPostParams = async (ctx: Ctx<any>): Promise<Record<string, string> | null> => {\n if (ctx.req.method !== \"POST\") return null\n\n const contentType = typeof ctx.req.headers[\"content-type\"] === \"string\" ? ctx.req.headers[\"content-type\"] : \"\"\n if (!contentType.includes(\"application/x-www-form-urlencoded\")) return null\n\n const body = await readTextBody(ctx.req as any)\n const params = new URLSearchParams(body)\n\n const result: Record<string, string> = {}\n for (const [key, value] of params.entries()) {\n result[key] = value\n }\n\n return result\n}\n\nconst resolveProviderId = (ctx: Ctx<any>, providerIdOverride?: string) =>\n (providerIdOverride ?? String(ctx.req.params?.provider ?? \"\")).trim()\n\nconst RESERVED_AUTH_PARAM_KEYS = new Set([\"__proto__\", \"prototype\", \"constructor\"])\n\nconst normalizeAuthorizationParams = (value: unknown): Record<string, string> | undefined => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return undefined\n\n const result: Record<string, string> = {}\n for (const [keyRaw, valueRaw] of Object.entries(value)) {\n const key = keyRaw.trim()\n if (!key) continue\n if (RESERVED_AUTH_PARAM_KEYS.has(key)) continue\n const val = typeof valueRaw === \"string\" ? valueRaw.trim() : \"\"\n if (!val) continue\n result[key] = val\n }\n\n return Object.keys(result).length ? result : undefined\n}\n\nexport type OAuthStartResult =\n | { success: true; redirectUrl: string }\n | { success: false; error: string; statusCode: number }\n\nexport const getOAuthStartRedirectUrl = async ({\n ctx,\n providerId: providerIdOverride,\n returnTo,\n authorizationParams,\n}: {\n ctx: Ctx<any>\n providerId?: string\n returnTo?: string | null\n authorizationParams?: Record<string, string>\n}): Promise<OAuthStartResult> => {\n const providerId = resolveProviderId(ctx, providerIdOverride)\n if (!providerId) {\n return { success: false, error: \"missing_provider\", statusCode: 400 }\n }\n\n if (!isSafeOAuthProviderId(providerId)) {\n return { success: false, error: \"invalid_provider\", statusCode: 400 }\n }\n\n const provider = getOAuthProviderConfig(providerId)\n if (!provider) {\n return { success: false, error: \"unknown_provider\", statusCode: 404 }\n }\n\n if (!ctx.req.session) {\n return { success: false, error: \"session_unavailable\", statusCode: 500 }\n }\n\n const origin = getRequestOrigin(ctx)\n if (!origin) {\n return { success: false, error: \"origin_unavailable\", statusCode: 500 }\n }\n\n const callbackPath = resolveCallbackPath(provider.callbackPath)\n if (!callbackPath) {\n return { success: false, error: \"invalid_callback_path\", statusCode: 500 }\n }\n\n const state = crypto.randomBytes(16).toString(\"hex\")\n const { verifier, challenge } = generatePkcePair()\n\n const sessionAny = ctx.req.session as any\n const rbOauthRaw = sessionAny.rbOauth\n if (!rbOauthRaw || typeof rbOauthRaw !== \"object\" || Array.isArray(rbOauthRaw)) {\n sessionAny.rbOauth = Object.create(null)\n } else if (Object.getPrototypeOf(rbOauthRaw) !== null) {\n sessionAny.rbOauth = Object.assign(Object.create(null), rbOauthRaw)\n }\n const safeReturnTo = typeof returnTo === \"string\" && isSafeRedirectPath(returnTo) ? returnTo : undefined\n sessionAny.rbOauth[providerId] = {\n state,\n codeVerifier: verifier,\n createdAt: Date.now(),\n returnTo: safeReturnTo,\n }\n\n const oidc = await getOidcWellKnown(provider.issuer)\n const redirectUri = `${origin}${callbackPath}`\n\n const url = new URL(oidc.authorization_endpoint)\n url.searchParams.set(\"client_id\", provider.clientId)\n url.searchParams.set(\"redirect_uri\", redirectUri)\n url.searchParams.set(\"response_type\", \"code\")\n url.searchParams.set(\"scope\", provider.scope)\n url.searchParams.set(\"state\", state)\n url.searchParams.set(\"code_challenge\", challenge)\n url.searchParams.set(\"code_challenge_method\", \"S256\")\n const extraAuthorizationParams = normalizeAuthorizationParams(authorizationParams)\n for (const [key, value] of Object.entries(extraAuthorizationParams ?? {})) {\n if (url.searchParams.has(key)) continue\n url.searchParams.set(key, value)\n }\n\n return { success: true, redirectUrl: url.toString() }\n}\n\nexport type OAuthCallbackResult =\n | {\n success: true\n type: \"signed_in\"\n redirectPath: string\n userId: string\n tenantId: string\n signedInTenants: string[]\n }\n | {\n success: false\n type: \"missing_user\"\n providerId: string\n subject: string\n email?: string\n name?: string\n redirectPath?: string\n }\n | {\n success: false\n type: \"error\"\n error: string\n redirectPath: string\n }\n\nconst OAUTH_SUCCESS_REDIRECT_PATH = \"/onboarding\"\nconst AUTH_ERROR_REDIRECT_BASE = \"/auth/sign-in\"\n\nexport const processOAuthCallback = async ({\n ctx,\n providerId: providerIdOverride,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n}: {\n ctx: Ctx<any>\n providerId?: string\n createUserOnFirstSignIn?: boolean\n missingUserRedirectPath?: string\n successRedirectPath?: string\n}): Promise<OAuthCallbackResult> => {\n const providerId = resolveProviderId(ctx, providerIdOverride)\n if (!providerId) {\n return { success: false, type: \"error\", error: \"missing_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_provider` }\n }\n\n if (!isSafeOAuthProviderId(providerId)) {\n return { success: false, type: \"error\", error: \"invalid_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_provider` }\n }\n\n const provider = getOAuthProviderConfig(providerId)\n if (!provider) {\n return { success: false, type: \"error\", error: \"unknown_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=unknown_provider` }\n }\n\n if (!ctx.req.session) {\n return { success: false, type: \"error\", error: \"session_unavailable\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=session_unavailable` }\n }\n\n const origin = getRequestOrigin(ctx)\n if (!origin) {\n return { success: false, type: \"error\", error: \"origin_unavailable\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=origin_unavailable` }\n }\n\n const callbackPath = resolveCallbackPath(provider.callbackPath)\n if (!callbackPath) {\n return { success: false, type: \"error\", error: \"invalid_callback_path\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_callback_path` }\n }\n\n const bodyParams = await getFormPostParams(ctx)\n\n const code = (getQueryString(bodyParams?.code) ?? getQueryString(ctx.req.query?.code))?.trim() ?? \"\"\n const state = (getQueryString(bodyParams?.state) ?? getQueryString(ctx.req.query?.state))?.trim() ?? \"\"\n const oauthUserRaw = (getQueryString(bodyParams?.user) ?? getQueryString(ctx.req.query?.user))?.trim() ?? \"\"\n\n const sessionAny = ctx.req.session as any\n const sessionState = sessionAny.rbOauth?.[providerId]\n const returnTo = typeof sessionState?.returnTo === \"string\" ? sessionState.returnTo : undefined\n\n if (!code || !state) {\n return { success: false, type: \"error\", error: \"missing_code_or_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_code_or_state` }\n }\n\n if (!sessionState || typeof sessionState.state !== \"string\" || sessionState.state !== state) {\n return { success: false, type: \"error\", error: \"invalid_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_state` }\n }\n\n const codeVerifier = typeof sessionState.codeVerifier === \"string\" ? sessionState.codeVerifier : \"\"\n if (!codeVerifier) {\n return { success: false, type: \"error\", error: \"missing_code_verifier\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_code_verifier` }\n }\n\n delete sessionAny.rbOauth?.[providerId]\n if (sessionAny.rbOauth && Object.keys(sessionAny.rbOauth).length === 0) {\n delete sessionAny.rbOauth\n }\n\n const oidc = await getOidcWellKnown(provider.issuer)\n const redirectUri = `${origin}${callbackPath}`\n\n const tokenBody = new URLSearchParams()\n tokenBody.set(\"grant_type\", \"authorization_code\")\n tokenBody.set(\"code\", code)\n tokenBody.set(\"redirect_uri\", redirectUri)\n tokenBody.set(\"client_id\", provider.clientId)\n tokenBody.set(\"code_verifier\", codeVerifier)\n if (provider.clientSecret) {\n tokenBody.set(\"client_secret\", provider.clientSecret)\n }\n\n const tokenResponse = await fetch(oidc.token_endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: tokenBody.toString(),\n })\n\n const tokenJson = await tokenResponse.json().catch(() => null) as Record<string, unknown> | null\n\n if (!tokenResponse.ok || !tokenJson || typeof tokenJson !== \"object\") {\n const body = tokenJson ? JSON.stringify(tokenJson) : \"\"\n console.warn(\"oauth::token_exchange failed\", tokenResponse.status, body)\n return { success: false, type: \"error\", error: \"token_exchange_failed\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=token_exchange_failed` }\n }\n\n const accessToken = typeof tokenJson.access_token === \"string\" ? tokenJson.access_token : \"\"\n const refreshToken = typeof tokenJson.refresh_token === \"string\" ? tokenJson.refresh_token : undefined\n const idToken = typeof tokenJson.id_token === \"string\" ? tokenJson.id_token : undefined\n const scope = typeof tokenJson.scope === \"string\" ? tokenJson.scope : undefined\n const tokenType = typeof tokenJson.token_type === \"string\" ? tokenJson.token_type : undefined\n const expiresIn = typeof tokenJson.expires_in === \"number\"\n ? tokenJson.expires_in\n : typeof tokenJson.expires_in === \"string\"\n ? Number(tokenJson.expires_in)\n : undefined\n const expiresInSeconds = typeof expiresIn === \"number\" && Number.isFinite(expiresIn) ? expiresIn : null\n const expiresAt = expiresInSeconds !== null ? new Date(Date.now() + expiresInSeconds * 1000) : undefined\n\n let userInfo: Record<string, unknown> | null = null\n\n if (oidc.userinfo_endpoint && accessToken) {\n const userInfoResponse = await fetch(oidc.userinfo_endpoint, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: \"application/json\",\n },\n })\n\n if (userInfoResponse.ok) {\n userInfo = await userInfoResponse.json().catch(() => null) as Record<string, unknown> | null\n }\n }\n\n const idTokenPayload = idToken ? decodeJwtPayload<Record<string, unknown>>(idToken) : null\n const accessTokenPayload = decodeJwtPayload<Record<string, unknown>>(accessToken)\n\n const subject = typeof userInfo?.sub === \"string\"\n ? userInfo.sub\n : typeof idTokenPayload?.sub === \"string\"\n ? idTokenPayload.sub\n : typeof accessTokenPayload?.sub === \"string\"\n ? accessTokenPayload.sub\n : \"\"\n\n if (!subject) {\n return { success: false, type: \"error\", error: \"missing_subject\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_subject` }\n }\n\n const email = typeof userInfo?.email === \"string\"\n ? userInfo.email\n : typeof idTokenPayload?.email === \"string\"\n ? idTokenPayload.email\n : undefined\n\n const name = typeof userInfo?.name === \"string\"\n ? userInfo.name\n : typeof idTokenPayload?.name === \"string\"\n ? idTokenPayload.name\n : undefined\n\n let oauthUser: unknown = null\n if (oauthUserRaw) {\n try {\n oauthUser = JSON.parse(oauthUserRaw) as unknown\n } catch {\n oauthUser = null\n }\n }\n const oauthUserEmail = typeof (oauthUser as any)?.email === \"string\" ? String((oauthUser as any).email).trim() : \"\"\n const oauthUserNameFirst = typeof (oauthUser as any)?.name?.firstName === \"string\" ? String((oauthUser as any).name.firstName).trim() : \"\"\n const oauthUserNameLast = typeof (oauthUser as any)?.name?.lastName === \"string\" ? String((oauthUser as any).name.lastName).trim() : \"\"\n const oauthUserName = [oauthUserNameFirst, oauthUserNameLast].filter(Boolean).join(\" \").trim()\n\n const resolvedEmail = email ?? (oauthUserEmail || undefined)\n const resolvedName = name ?? (oauthUserName || undefined)\n\n const [User, Tenant] = await Promise.all([\n models.getGlobal(\"RBUser\", ctx),\n models.getGlobal(\"RBTenant\", ctx),\n ])\n\n const subjectQueryKey = `oauthProviders.${providerId}.subject`\n let user = await (User as any).findOne({ [subjectQueryKey]: subject })\n\n if (!user && resolvedEmail) {\n user = await (User as any).findOne({ email: resolvedEmail })\n }\n\n const shouldCreateUser = createUserOnFirstSignIn ?? true\n if (!user && !shouldCreateUser) {\n const redirectPath = missingUserRedirectPath\n\n const result: OAuthCallbackResult = {\n success: false,\n type: \"missing_user\",\n providerId,\n subject,\n email: resolvedEmail,\n name: resolvedName,\n }\n\n if (redirectPath && isSafeRedirectPath(redirectPath)) {\n const url = new URL(redirectPath, origin)\n url.searchParams.set(\"oauth_provider\", providerId)\n if (resolvedEmail) url.searchParams.set(\"email\", resolvedEmail)\n if (resolvedName) url.searchParams.set(\"name\", resolvedName)\n result.redirectPath = `${url.pathname}${url.search}`\n }\n\n return result\n }\n\n const now = new Date()\n\n let providerCreatedAt: Date | undefined\n const oauthProvidersValue = user ? (user as any).oauthProviders : undefined\n if (oauthProvidersValue instanceof Map) {\n const existing = oauthProvidersValue.get(providerId)\n if (existing?.createdAt instanceof Date) providerCreatedAt = existing.createdAt\n } else if (oauthProvidersValue && typeof oauthProvidersValue === \"object\") {\n const existing = (oauthProvidersValue as any)[providerId]\n if (existing?.createdAt instanceof Date) providerCreatedAt = existing.createdAt\n }\n\n const oauthProviderPayload = {\n subject,\n email: resolvedEmail,\n name: resolvedName,\n accessToken,\n refreshToken,\n idToken,\n scope,\n tokenType,\n expiresAt,\n rawUserInfo: userInfo ?? undefined,\n createdAt: providerCreatedAt ?? now,\n updatedAt: now,\n }\n\n if (!user) {\n const tenantId = crypto.randomUUID()\n const password = await hashPasswordForStorage(crypto.randomBytes(32).toString(\"hex\"))\n\n user = new (User as any)({\n email: resolvedEmail,\n name: resolvedName,\n password,\n tenants: [tenantId],\n tenantRoles: {\n [tenantId]: [\"owner\"],\n },\n oauthProviders: {\n [providerId]: oauthProviderPayload,\n },\n })\n\n await user.save()\n\n try {\n await (Tenant as any).create({\n tenantId,\n name: resolvedEmail || subject,\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_create_tenant\", err)\n }\n } else {\n const setFields: Record<string, unknown> = {\n [`oauthProviders.${providerId}`]: oauthProviderPayload,\n }\n\n if (!user.email && resolvedEmail) {\n setFields.email = resolvedEmail\n }\n\n if (!user.name && resolvedName) {\n setFields.name = resolvedName\n }\n\n await (User as any).updateOne({ _id: user._id }, { $set: setFields })\n }\n\n const tenantId = user.tenants?.[0]?.toString?.() || \"00000000\"\n const signedInTenants = (user.tenants || []).map((t: any) => t.toString?.() || String(t)) || [tenantId]\n\n const tenantRolesRaw = (user as unknown as { tenantRoles?: unknown }).tenantRoles\n const tenantRoles = tenantRolesRaw instanceof Map\n ? Object.fromEntries(tenantRolesRaw.entries())\n : tenantRolesRaw && typeof tenantRolesRaw === \"object\"\n ? tenantRolesRaw\n : undefined\n\n ctx.req.session.user = {\n id: user._id.toString(),\n currentTenantId: tenantId,\n signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],\n isEntryGateAuthorized: true,\n tenantRoles,\n }\n\n const redirectPath = returnTo && isSafeRedirectPath(returnTo)\n ? returnTo\n : successRedirectPath && isSafeRedirectPath(successRedirectPath)\n ? successRedirectPath\n : OAUTH_SUCCESS_REDIRECT_PATH\n\n return {\n success: true,\n type: \"signed_in\",\n redirectPath,\n userId: user._id.toString(),\n tenantId,\n signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],\n }\n}\n\nexport const createOAuthStartHandler = ({\n providerId,\n getAuthorizationParams,\n}: {\n providerId?: string\n getAuthorizationParams?: (providerId: string) => Record<string, string> | undefined\n} = {}): ApiHandler<any, { success: boolean; error?: string }, any> => async (\n _payload,\n ctx,\n) => {\n const resolvedProviderId = resolveProviderId(ctx, providerId)\n const providerAuthorizationParams = resolvedProviderId && getAuthorizationParams\n ? getAuthorizationParams(resolvedProviderId)\n : undefined\n const returnTo = getQueryString(ctx.req.query?.returnTo)?.trim()\n const result = await getOAuthStartRedirectUrl({\n ctx,\n providerId: resolvedProviderId,\n returnTo,\n authorizationParams: providerAuthorizationParams,\n })\n\n if (!result.success) {\n ctx.res.status(result.statusCode)\n return { success: false, error: result.error }\n }\n\n ctx.res.redirect(result.redirectUrl)\n return { success: true }\n}\n\nexport const createOAuthCallbackHandler = ({\n providerId,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n}: {\n providerId?: string\n createUserOnFirstSignIn?: boolean\n missingUserRedirectPath?: string\n successRedirectPath?: string\n} = {}): ApiHandler<any, { success: boolean; error?: string }, any> => async (\n _payload,\n ctx,\n) => {\n const result = await processOAuthCallback({\n ctx,\n providerId,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n })\n\n if (result.type === \"error\") {\n ctx.res.redirect(result.redirectPath)\n return { success: false, error: result.error }\n }\n\n if (result.type === \"missing_user\") {\n if (result.redirectPath) {\n ctx.res.redirect(result.redirectPath)\n } else {\n ctx.res.redirect(\"/auth/sign-up\")\n }\n return { success: false, error: \"user_not_found\" }\n }\n\n ctx.res.redirect(result.redirectPath)\n return { success: true }\n}\n\nconst base64UrlEncode = (input: Buffer | string) =>\n Buffer.from(input)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/g, \"\")\n\nexport const createAppleClientSecret = ({\n teamId,\n clientId,\n keyId,\n privateKeyPem,\n now = new Date(),\n expiresInSeconds = 10 * 60,\n}: {\n teamId: string\n clientId: string\n keyId: string\n privateKeyPem: string\n now?: Date\n expiresInSeconds?: number\n}) => {\n const teamIdValue = teamId.trim()\n const clientIdValue = clientId.trim()\n const keyIdValue = keyId.trim()\n const privateKeyPemValue = privateKeyPem.trim()\n\n if (!teamIdValue) throw new Error(\"teamId is required\")\n if (!clientIdValue) throw new Error(\"clientId is required\")\n if (!keyIdValue) throw new Error(\"keyId is required\")\n if (!privateKeyPemValue) throw new Error(\"privateKeyPem is required\")\n\n const nowSeconds = Math.floor(now.getTime() / 1000)\n const expiresIn = Number.isFinite(expiresInSeconds) ? expiresInSeconds : 10 * 60\n const exp = nowSeconds + Math.max(60, Math.min(expiresIn, 60 * 60 * 24 * 180))\n\n const header = { alg: \"ES256\", kid: keyIdValue, typ: \"JWT\" }\n const payload = {\n iss: teamIdValue,\n iat: nowSeconds,\n exp,\n aud: \"https://appleid.apple.com\",\n sub: clientIdValue,\n }\n\n const signingInput = `${base64UrlEncode(JSON.stringify(header))}.${base64UrlEncode(JSON.stringify(payload))}`\n const signature = crypto.sign(\"sha256\", Buffer.from(signingInput), {\n key: privateKeyPemValue,\n dsaEncoding: \"ieee-p1363\",\n })\n\n return `${signingInput}.${base64UrlEncode(signature)}`\n}\n"],"names":["isSafeRedirectPath","base64UrlEncode","redirectPath","tenantId"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/oauth/config.ts","../../src/oauth/jwt.ts","../../src/oauth/oidc.ts","../../src/oauth/pkce.ts","../../src/oauth/providerId.ts","../../src/oauth/lib.ts"],"sourcesContent":["export type OAuthProviderConfig = {\n issuer: string\n clientId: string\n clientSecret?: string\n scope: string\n callbackPath: string\n}\n\ntype OAuthProvidersConfig = Record<string, OAuthProviderConfig>\n\ntype OAuthProvidersStore = {\n providers: OAuthProvidersConfig\n}\n\nconst STORE_KEY = Symbol.for(\"@rpcbase/auth/oauthProviders\")\n\nconst getStore = (): OAuthProvidersStore => {\n const anyGlobal = globalThis as unknown as Record<string | symbol, unknown>\n const existing = anyGlobal[STORE_KEY] as OAuthProvidersStore | undefined\n if (existing && typeof existing === \"object\" && existing.providers && typeof existing.providers === \"object\") {\n return existing\n }\n\n const created: OAuthProvidersStore = { providers: {} }\n anyGlobal[STORE_KEY] = created\n return created\n}\n\nconst normalizeProviders = (providers: Record<string, OAuthProviderConfig>): OAuthProvidersConfig => {\n const result: OAuthProvidersConfig = {}\n\n const isSafeRedirectPath = (candidate: string) => {\n if (!candidate.startsWith(\"/\")) return false\n if (candidate.startsWith(\"//\")) return false\n return true\n }\n\n for (const [providerIdRaw, value] of Object.entries(providers)) {\n const providerId = providerIdRaw.trim()\n if (!providerId) continue\n\n const issuer = typeof value?.issuer === \"string\" ? value.issuer.trim() : \"\"\n const clientId = typeof value?.clientId === \"string\" ? value.clientId.trim() : \"\"\n if (!issuer) throw new Error(`oauth provider \"${providerId}\" missing issuer`)\n if (!clientId) throw new Error(`oauth provider \"${providerId}\" missing clientId`)\n\n const clientSecret = typeof value?.clientSecret === \"string\" && value.clientSecret.trim()\n ? value.clientSecret\n : undefined\n\n const scope = typeof value?.scope === \"string\" ? value.scope.trim() : \"\"\n if (!scope) throw new Error(`oauth provider \"${providerId}\" missing scope`)\n\n const callbackPath = typeof value?.callbackPath === \"string\"\n ? value.callbackPath.trim()\n : \"\"\n if (!callbackPath) throw new Error(`oauth provider \"${providerId}\" missing callbackPath`)\n if (!isSafeRedirectPath(callbackPath)) throw new Error(`oauth provider \"${providerId}\" has invalid callbackPath`)\n\n result[providerId] = {\n issuer,\n clientId,\n clientSecret,\n scope,\n callbackPath,\n }\n }\n\n return result\n}\n\nexport const configureOAuthProviders = (providers: Record<string, OAuthProviderConfig>) => {\n const store = getStore()\n const normalized = normalizeProviders(providers)\n store.providers = { ...store.providers, ...normalized }\n}\n\nexport const setOAuthProviders = (providers: Record<string, OAuthProviderConfig>) => {\n const store = getStore()\n store.providers = normalizeProviders(providers)\n}\n\nexport const getOAuthProviderConfig = (providerId: string): OAuthProviderConfig | null => {\n const store = getStore()\n return store.providers[providerId] ?? null\n}\n","const decodeBase64Url = (value: string) => {\n const padded = value.replace(/-/g, \"+\").replace(/_/g, \"/\") + \"===\".slice((value.length + 3) % 4)\n return Buffer.from(padded, \"base64\").toString(\"utf8\")\n}\n\nexport const decodeJwtPayload = <T = Record<string, unknown>>(token: string): T | null => {\n const parts = token.split(\".\")\n if (parts.length < 2) return null\n\n try {\n const json = decodeBase64Url(parts[1])\n const parsed = JSON.parse(json) as T\n if (!parsed || typeof parsed !== \"object\") return null\n return parsed\n } catch {\n return null\n }\n}\n\n","export type OidcWellKnown = {\n issuer: string\n authorization_endpoint: string\n token_endpoint: string\n userinfo_endpoint?: string\n jwks_uri?: string\n}\n\nconst cache = new Map<string, Promise<OidcWellKnown>>()\n\nconst normalizeIssuer = (raw: string) => raw.trim().replace(/\\/+$/, \"\")\n\nexport const getOidcWellKnown = async (issuerRaw: string): Promise<OidcWellKnown> => {\n const issuer = normalizeIssuer(issuerRaw)\n if (!issuer) {\n throw new Error(\"OIDC issuer is required\")\n }\n\n const existing = cache.get(issuer)\n if (existing) {\n return existing\n }\n\n const loader = (async () => {\n const url = new URL(\"/.well-known/openid-configuration\", issuer)\n const response = await fetch(url, { headers: { Accept: \"application/json\" } })\n if (!response.ok) {\n const body = await response.text().catch(() => \"\")\n throw new Error(`Failed to fetch OIDC discovery document: ${response.status} ${body}`)\n }\n\n const json = await response.json().catch(() => null) as Partial<OidcWellKnown> | null\n if (!json || typeof json !== \"object\") {\n throw new Error(\"Invalid OIDC discovery document\")\n }\n\n const authorizationEndpoint = typeof json.authorization_endpoint === \"string\"\n ? json.authorization_endpoint\n : \"\"\n const tokenEndpoint = typeof json.token_endpoint === \"string\"\n ? json.token_endpoint\n : \"\"\n const issuerValue = typeof json.issuer === \"string\" ? json.issuer : issuer\n const userinfoEndpoint = typeof json.userinfo_endpoint === \"string\" ? json.userinfo_endpoint : undefined\n const jwksUri = typeof json.jwks_uri === \"string\" ? json.jwks_uri : undefined\n\n if (!authorizationEndpoint || !tokenEndpoint) {\n throw new Error(\"OIDC discovery document missing required endpoints\")\n }\n\n return {\n issuer: issuerValue,\n authorization_endpoint: authorizationEndpoint,\n token_endpoint: tokenEndpoint,\n userinfo_endpoint: userinfoEndpoint,\n jwks_uri: jwksUri,\n } satisfies OidcWellKnown\n })()\n\n cache.set(issuer, loader)\n\n try {\n return await loader\n } catch (err) {\n cache.delete(issuer)\n throw err\n }\n}\n\n","import crypto from \"crypto\"\n\n\nexport const base64UrlEncode = (input: Buffer) => input\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/g, \"\")\n\nexport const generatePkcePair = () => {\n const verifier = base64UrlEncode(crypto.randomBytes(32))\n const challenge = base64UrlEncode(crypto.createHash(\"sha256\").update(verifier).digest())\n\n return { verifier, challenge }\n}\n\n","const RESERVED_KEYS = new Set([\"__proto__\", \"prototype\", \"constructor\"])\n\nexport const isSafeOAuthProviderId = (value: string) => {\n const providerId = value.trim()\n if (!providerId) return false\n if (providerId.length > 128) return false\n if (RESERVED_KEYS.has(providerId)) return false\n return /^[a-zA-Z0-9_-]+$/.test(providerId)\n}\n\n","import crypto from \"crypto\"\n\nimport { ApiHandler, Ctx } from \"@rpcbase/api\"\nimport { models } from \"@rpcbase/db\"\nimport { hashPasswordForStorage } from \"@rpcbase/server\"\n\nimport { getOAuthProviderConfig } from \"./config\"\nimport { decodeJwtPayload } from \"./jwt\"\nimport { getOidcWellKnown } from \"./oidc\"\nimport { generatePkcePair } from \"./pkce\"\nimport { isSafeOAuthProviderId } from \"./providerId\"\n\n\nconst OAUTH_REQUEST_TTL_MS = 10 * 60 * 1000\nconst OAUTH_STATE_COOKIE_NAME = \"rb_oauth_state\"\n\nconst getQueryString = (value: unknown) => {\n if (typeof value === \"string\") return value\n if (Array.isArray(value) && typeof value[0] === \"string\") return value[0]\n return null\n}\n\nconst getCookieValue = (ctx: Ctx<any>, name: string): string | null => {\n const header = ctx.req.headers?.cookie\n if (typeof header !== \"string\" || !header) return null\n\n for (const part of header.split(\";\")) {\n const [rawKey, ...rest] = part.split(\"=\")\n const key = rawKey?.trim()\n if (!key || key !== name) continue\n const rawValue = rest.join(\"=\").trim()\n if (!rawValue) return \"\"\n try {\n return decodeURIComponent(rawValue)\n } catch {\n return rawValue\n }\n }\n\n return null\n}\n\nconst isSafeRedirectPath = (candidate: string) => {\n if (!candidate.startsWith(\"/\")) return false\n if (candidate.startsWith(\"//\")) return false\n return true\n}\n\nconst getRequestOrigin = (ctx: Ctx<any>) => {\n const protoHeader = ctx.req.headers[\"x-forwarded-proto\"]\n const hostHeader = ctx.req.headers[\"x-forwarded-host\"]\n\n const protocol = typeof protoHeader === \"string\"\n ? protoHeader.split(\",\")[0].trim()\n : ctx.req.protocol\n\n const host = typeof hostHeader === \"string\"\n ? hostHeader.split(\",\")[0].trim()\n : ctx.req.get(\"host\")\n\n return protocol && host ? `${protocol}://${host}` : \"\"\n}\n\nconst resolveCallbackPath = (callbackPath: string) => {\n const trimmed = callbackPath.trim()\n return trimmed && isSafeRedirectPath(trimmed) ? trimmed : null\n}\n\nconst readTextBody = async (req: { on: (event: string, cb: (arg: any) => void) => void; setEncoding?: (enc: string) => void }) =>\n await new Promise<string>((resolve, reject) => {\n let body = \"\"\n if (typeof req.setEncoding === \"function\") {\n req.setEncoding(\"utf8\")\n }\n\n req.on(\"data\", (chunk: string) => {\n body += chunk\n if (body.length > 32_768) {\n reject(new Error(\"request_body_too_large\"))\n }\n })\n req.on(\"end\", () => resolve(body))\n req.on(\"error\", reject)\n })\n\nconst getFormPostParams = async (ctx: Ctx<any>): Promise<Record<string, string> | null> => {\n if (ctx.req.method !== \"POST\") return null\n\n const contentType = typeof ctx.req.headers[\"content-type\"] === \"string\" ? ctx.req.headers[\"content-type\"] : \"\"\n if (!contentType.includes(\"application/x-www-form-urlencoded\")) return null\n\n const body = await readTextBody(ctx.req as any)\n const params = new URLSearchParams(body)\n\n const result: Record<string, string> = {}\n for (const [key, value] of params.entries()) {\n result[key] = value\n }\n\n return result\n}\n\nconst resolveProviderId = (ctx: Ctx<any>, providerIdOverride?: string) =>\n (providerIdOverride ?? String(ctx.req.params?.provider ?? \"\")).trim()\n\nconst RESERVED_AUTH_PARAM_KEYS = new Set([\"__proto__\", \"prototype\", \"constructor\"])\n\nconst normalizeAuthorizationParams = (value: unknown): Record<string, string> | undefined => {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return undefined\n\n const result: Record<string, string> = {}\n for (const [keyRaw, valueRaw] of Object.entries(value)) {\n const key = keyRaw.trim()\n if (!key) continue\n if (RESERVED_AUTH_PARAM_KEYS.has(key)) continue\n const val = typeof valueRaw === \"string\" ? valueRaw.trim() : \"\"\n if (!val) continue\n result[key] = val\n }\n\n return Object.keys(result).length ? result : undefined\n}\n\nexport type OAuthStartResult =\n | { success: true; redirectUrl: string }\n | { success: false; error: string; statusCode: number }\n\nexport const getOAuthStartRedirectUrl = async ({\n ctx,\n providerId: providerIdOverride,\n returnTo,\n authorizationParams,\n}: {\n ctx: Ctx<any>\n providerId?: string\n returnTo?: string | null\n authorizationParams?: Record<string, string>\n}): Promise<OAuthStartResult> => {\n const providerId = resolveProviderId(ctx, providerIdOverride)\n if (!providerId) {\n return { success: false, error: \"missing_provider\", statusCode: 400 }\n }\n\n if (!isSafeOAuthProviderId(providerId)) {\n return { success: false, error: \"invalid_provider\", statusCode: 400 }\n }\n\n const provider = getOAuthProviderConfig(providerId)\n if (!provider) {\n return { success: false, error: \"unknown_provider\", statusCode: 404 }\n }\n\n const origin = getRequestOrigin(ctx)\n if (!origin) {\n return { success: false, error: \"origin_unavailable\", statusCode: 500 }\n }\n const isHttps = origin.startsWith(\"https://\")\n\n const callbackPath = resolveCallbackPath(provider.callbackPath)\n if (!callbackPath) {\n return { success: false, error: \"invalid_callback_path\", statusCode: 500 }\n }\n\n const state = crypto.randomBytes(16).toString(\"hex\")\n const { verifier, challenge } = generatePkcePair()\n\n const safeReturnTo = typeof returnTo === \"string\" && isSafeRedirectPath(returnTo) ? returnTo : undefined\n\n try {\n const OAuthRequest = await models.getGlobal(\"RBOAuthRequest\", ctx)\n const now = new Date()\n await OAuthRequest.create({\n _id: state,\n providerId,\n codeVerifier: verifier,\n returnTo: safeReturnTo,\n createdAt: now,\n expiresAt: new Date(now.getTime() + OAUTH_REQUEST_TTL_MS),\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_store_request\", err)\n return { success: false, error: \"oauth_request_store_failed\", statusCode: 500 }\n }\n\n try {\n ;(ctx.res as any).cookie(OAUTH_STATE_COOKIE_NAME, `${providerId}:${state}`, {\n httpOnly: true,\n secure: isHttps,\n sameSite: isHttps ? \"none\" : \"lax\",\n path: callbackPath,\n maxAge: OAUTH_REQUEST_TTL_MS,\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_set_state_cookie\", err)\n return { success: false, error: \"oauth_cookie_set_failed\", statusCode: 500 }\n }\n\n const oidc = await getOidcWellKnown(provider.issuer)\n const redirectUri = `${origin}${callbackPath}`\n\n const url = new URL(oidc.authorization_endpoint)\n url.searchParams.set(\"client_id\", provider.clientId)\n url.searchParams.set(\"redirect_uri\", redirectUri)\n url.searchParams.set(\"response_type\", \"code\")\n url.searchParams.set(\"scope\", provider.scope)\n url.searchParams.set(\"state\", state)\n url.searchParams.set(\"code_challenge\", challenge)\n url.searchParams.set(\"code_challenge_method\", \"S256\")\n const extraAuthorizationParams = normalizeAuthorizationParams(authorizationParams)\n for (const [key, value] of Object.entries(extraAuthorizationParams ?? {})) {\n if (url.searchParams.has(key)) continue\n url.searchParams.set(key, value)\n }\n\n return { success: true, redirectUrl: url.toString() }\n}\n\nexport type OAuthCallbackResult =\n | {\n success: true\n type: \"signed_in\"\n redirectPath: string\n userId: string\n tenantId: string\n signedInTenants: string[]\n }\n | {\n success: false\n type: \"missing_user\"\n providerId: string\n subject: string\n email?: string\n name?: string\n redirectPath?: string\n }\n | {\n success: false\n type: \"error\"\n error: string\n redirectPath: string\n }\n\nconst OAUTH_SUCCESS_REDIRECT_PATH = \"/onboarding\"\nconst AUTH_ERROR_REDIRECT_BASE = \"/auth/sign-in\"\n\nexport const processOAuthCallback = async ({\n ctx,\n providerId: providerIdOverride,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n}: {\n ctx: Ctx<any>\n providerId?: string\n createUserOnFirstSignIn?: boolean\n missingUserRedirectPath?: string\n successRedirectPath?: string\n}): Promise<OAuthCallbackResult> => {\n const providerId = resolveProviderId(ctx, providerIdOverride)\n if (!providerId) {\n return { success: false, type: \"error\", error: \"missing_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_provider` }\n }\n\n if (!isSafeOAuthProviderId(providerId)) {\n return { success: false, type: \"error\", error: \"invalid_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_provider` }\n }\n\n const provider = getOAuthProviderConfig(providerId)\n if (!provider) {\n return { success: false, type: \"error\", error: \"unknown_provider\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=unknown_provider` }\n }\n\n const origin = getRequestOrigin(ctx)\n if (!origin) {\n return { success: false, type: \"error\", error: \"origin_unavailable\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=origin_unavailable` }\n }\n const isHttps = origin.startsWith(\"https://\")\n\n const callbackPath = resolveCallbackPath(provider.callbackPath)\n if (!callbackPath) {\n return { success: false, type: \"error\", error: \"invalid_callback_path\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_callback_path` }\n }\n\n const bodyParams = await getFormPostParams(ctx)\n\n const code = (getQueryString(bodyParams?.code) ?? getQueryString(ctx.req.query?.code))?.trim() ?? \"\"\n const state = (getQueryString(bodyParams?.state) ?? getQueryString(ctx.req.query?.state))?.trim() ?? \"\"\n const oauthUserRaw = (getQueryString(bodyParams?.user) ?? getQueryString(ctx.req.query?.user))?.trim() ?? \"\"\n\n if (!code || !state) {\n return { success: false, type: \"error\", error: \"missing_code_or_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_code_or_state` }\n }\n\n const stateCookieValue = getCookieValue(ctx, OAUTH_STATE_COOKIE_NAME)\n if (stateCookieValue !== `${providerId}:${state}`) {\n return { success: false, type: \"error\", error: \"invalid_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_state` }\n }\n\n let oauthRequest: any = null\n let OAuthRequestModel: any = null\n try {\n OAuthRequestModel = await models.getGlobal(\"RBOAuthRequest\", ctx)\n oauthRequest = await OAuthRequestModel.findOne({ _id: state, providerId }).lean()\n } catch (err) {\n console.warn(\"oauth::failed_to_load_request\", err)\n return { success: false, type: \"error\", error: \"oauth_request_load_failed\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=oauth_request_load_failed` }\n }\n\n if (!oauthRequest) {\n return { success: false, type: \"error\", error: \"invalid_state\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=invalid_state` }\n }\n\n const returnTo = typeof oauthRequest.returnTo === \"string\" ? oauthRequest.returnTo : undefined\n const codeVerifier = typeof oauthRequest.codeVerifier === \"string\" ? oauthRequest.codeVerifier : \"\"\n if (!codeVerifier) {\n return { success: false, type: \"error\", error: \"missing_code_verifier\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_code_verifier` }\n }\n\n const oidc = await getOidcWellKnown(provider.issuer)\n const redirectUri = `${origin}${callbackPath}`\n\n const tokenBody = new URLSearchParams()\n tokenBody.set(\"grant_type\", \"authorization_code\")\n tokenBody.set(\"code\", code)\n tokenBody.set(\"redirect_uri\", redirectUri)\n tokenBody.set(\"client_id\", provider.clientId)\n tokenBody.set(\"code_verifier\", codeVerifier)\n if (provider.clientSecret) {\n tokenBody.set(\"client_secret\", provider.clientSecret)\n }\n\n const tokenResponse = await fetch(oidc.token_endpoint, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n Accept: \"application/json\",\n },\n body: tokenBody.toString(),\n })\n\n const tokenJson = await tokenResponse.json().catch(() => null) as Record<string, unknown> | null\n\n if (!tokenResponse.ok || !tokenJson || typeof tokenJson !== \"object\") {\n const body = tokenJson ? JSON.stringify(tokenJson) : \"\"\n console.warn(\"oauth::token_exchange failed\", tokenResponse.status, body)\n return { success: false, type: \"error\", error: \"token_exchange_failed\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=token_exchange_failed` }\n }\n\n const accessToken = typeof tokenJson.access_token === \"string\" ? tokenJson.access_token : \"\"\n const refreshToken = typeof tokenJson.refresh_token === \"string\" ? tokenJson.refresh_token : undefined\n const idToken = typeof tokenJson.id_token === \"string\" ? tokenJson.id_token : undefined\n const scope = typeof tokenJson.scope === \"string\" ? tokenJson.scope : undefined\n const tokenType = typeof tokenJson.token_type === \"string\" ? tokenJson.token_type : undefined\n const expiresIn = typeof tokenJson.expires_in === \"number\"\n ? tokenJson.expires_in\n : typeof tokenJson.expires_in === \"string\"\n ? Number(tokenJson.expires_in)\n : undefined\n const expiresInSeconds = typeof expiresIn === \"number\" && Number.isFinite(expiresIn) ? expiresIn : null\n const expiresAt = expiresInSeconds !== null ? new Date(Date.now() + expiresInSeconds * 1000) : undefined\n\n let userInfo: Record<string, unknown> | null = null\n\n if (oidc.userinfo_endpoint && accessToken) {\n const userInfoResponse = await fetch(oidc.userinfo_endpoint, {\n headers: {\n Authorization: `Bearer ${accessToken}`,\n Accept: \"application/json\",\n },\n })\n\n if (userInfoResponse.ok) {\n userInfo = await userInfoResponse.json().catch(() => null) as Record<string, unknown> | null\n }\n }\n\n const idTokenPayload = idToken ? decodeJwtPayload<Record<string, unknown>>(idToken) : null\n const accessTokenPayload = decodeJwtPayload<Record<string, unknown>>(accessToken)\n\n const subject = typeof userInfo?.sub === \"string\"\n ? userInfo.sub\n : typeof idTokenPayload?.sub === \"string\"\n ? idTokenPayload.sub\n : typeof accessTokenPayload?.sub === \"string\"\n ? accessTokenPayload.sub\n : \"\"\n\n if (!subject) {\n return { success: false, type: \"error\", error: \"missing_subject\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=missing_subject` }\n }\n\n const email = typeof userInfo?.email === \"string\"\n ? userInfo.email\n : typeof idTokenPayload?.email === \"string\"\n ? idTokenPayload.email\n : undefined\n\n const name = typeof userInfo?.name === \"string\"\n ? userInfo.name\n : typeof idTokenPayload?.name === \"string\"\n ? idTokenPayload.name\n : undefined\n\n let oauthUser: unknown = null\n if (oauthUserRaw) {\n try {\n oauthUser = JSON.parse(oauthUserRaw) as unknown\n } catch {\n oauthUser = null\n }\n }\n const oauthUserEmail = typeof (oauthUser as any)?.email === \"string\" ? String((oauthUser as any).email).trim() : \"\"\n const oauthUserNameFirst = typeof (oauthUser as any)?.name?.firstName === \"string\" ? String((oauthUser as any).name.firstName).trim() : \"\"\n const oauthUserNameLast = typeof (oauthUser as any)?.name?.lastName === \"string\" ? String((oauthUser as any).name.lastName).trim() : \"\"\n const oauthUserName = [oauthUserNameFirst, oauthUserNameLast].filter(Boolean).join(\" \").trim()\n\n const resolvedEmail = email ?? (oauthUserEmail || undefined)\n const resolvedName = name ?? (oauthUserName || undefined)\n\n const [User, Tenant] = await Promise.all([\n models.getGlobal(\"RBUser\", ctx),\n models.getGlobal(\"RBTenant\", ctx),\n ])\n\n const subjectQueryKey = `oauthProviders.${providerId}.subject`\n let user = await (User as any).findOne({ [subjectQueryKey]: subject })\n\n if (!user && resolvedEmail) {\n user = await (User as any).findOne({ email: resolvedEmail })\n }\n\n const shouldCreateUser = createUserOnFirstSignIn ?? true\n if (!user && !shouldCreateUser) {\n const redirectPath = missingUserRedirectPath\n\n const result: OAuthCallbackResult = {\n success: false,\n type: \"missing_user\",\n providerId,\n subject,\n email: resolvedEmail,\n name: resolvedName,\n }\n\n if (redirectPath && isSafeRedirectPath(redirectPath)) {\n const url = new URL(redirectPath, origin)\n url.searchParams.set(\"oauth_provider\", providerId)\n if (resolvedEmail) url.searchParams.set(\"email\", resolvedEmail)\n if (resolvedName) url.searchParams.set(\"name\", resolvedName)\n result.redirectPath = `${url.pathname}${url.search}`\n }\n\n return result\n }\n\n if (!ctx.req.session) {\n return { success: false, type: \"error\", error: \"session_unavailable\", redirectPath: `${AUTH_ERROR_REDIRECT_BASE}?error=session_unavailable` }\n }\n\n const now = new Date()\n\n let providerCreatedAt: Date | undefined\n const oauthProvidersValue = user ? (user as any).oauthProviders : undefined\n if (oauthProvidersValue instanceof Map) {\n const existing = oauthProvidersValue.get(providerId)\n if (existing?.createdAt instanceof Date) providerCreatedAt = existing.createdAt\n } else if (oauthProvidersValue && typeof oauthProvidersValue === \"object\") {\n const existing = (oauthProvidersValue as any)[providerId]\n if (existing?.createdAt instanceof Date) providerCreatedAt = existing.createdAt\n }\n\n const oauthProviderPayload = {\n subject,\n email: resolvedEmail,\n name: resolvedName,\n accessToken,\n refreshToken,\n idToken,\n scope,\n tokenType,\n expiresAt,\n rawUserInfo: userInfo ?? undefined,\n createdAt: providerCreatedAt ?? now,\n updatedAt: now,\n }\n\n if (!user) {\n const tenantId = crypto.randomUUID()\n const password = await hashPasswordForStorage(crypto.randomBytes(32).toString(\"hex\"))\n\n user = new (User as any)({\n email: resolvedEmail,\n name: resolvedName,\n password,\n tenants: [tenantId],\n tenantRoles: {\n [tenantId]: [\"owner\"],\n },\n oauthProviders: {\n [providerId]: oauthProviderPayload,\n },\n })\n\n await user.save()\n\n try {\n await (Tenant as any).create({\n tenantId,\n name: resolvedEmail || subject,\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_create_tenant\", err)\n }\n } else {\n const setFields: Record<string, unknown> = {\n [`oauthProviders.${providerId}`]: oauthProviderPayload,\n }\n\n if (!user.email && resolvedEmail) {\n setFields.email = resolvedEmail\n }\n\n if (!user.name && resolvedName) {\n setFields.name = resolvedName\n }\n\n await (User as any).updateOne({ _id: user._id }, { $set: setFields })\n }\n\n const tenantId = user.tenants?.[0]?.toString?.() || \"00000000\"\n const signedInTenants = (user.tenants || []).map((t: any) => t.toString?.() || String(t)) || [tenantId]\n\n const tenantRolesRaw = (user as unknown as { tenantRoles?: unknown }).tenantRoles\n const tenantRoles = tenantRolesRaw instanceof Map\n ? Object.fromEntries(tenantRolesRaw.entries())\n : tenantRolesRaw && typeof tenantRolesRaw === \"object\"\n ? tenantRolesRaw\n : undefined\n\n ctx.req.session.user = {\n id: user._id.toString(),\n currentTenantId: tenantId,\n signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],\n isEntryGateAuthorized: true,\n tenantRoles,\n }\n\n try {\n if (OAuthRequestModel) {\n await OAuthRequestModel.deleteOne({ _id: state, providerId })\n }\n } catch (err) {\n console.warn(\"oauth::failed_to_delete_request\", err)\n }\n\n try {\n ;(ctx.res as any).clearCookie(OAUTH_STATE_COOKIE_NAME, {\n httpOnly: true,\n secure: isHttps,\n sameSite: isHttps ? \"none\" : \"lax\",\n path: callbackPath,\n })\n } catch (err) {\n console.warn(\"oauth::failed_to_clear_state_cookie\", err)\n }\n\n const redirectPath = returnTo && isSafeRedirectPath(returnTo)\n ? returnTo\n : successRedirectPath && isSafeRedirectPath(successRedirectPath)\n ? successRedirectPath\n : OAUTH_SUCCESS_REDIRECT_PATH\n\n return {\n success: true,\n type: \"signed_in\",\n redirectPath,\n userId: user._id.toString(),\n tenantId,\n signedInTenants: signedInTenants.length ? signedInTenants : [tenantId],\n }\n}\n\nexport const createOAuthStartHandler = ({\n providerId,\n getAuthorizationParams,\n}: {\n providerId?: string\n getAuthorizationParams?: (providerId: string) => Record<string, string> | undefined\n} = {}): ApiHandler<any, { success: boolean; error?: string }, any> => async (\n _payload,\n ctx,\n) => {\n const resolvedProviderId = resolveProviderId(ctx, providerId)\n const providerAuthorizationParams = resolvedProviderId && getAuthorizationParams\n ? getAuthorizationParams(resolvedProviderId)\n : undefined\n const returnTo = getQueryString(ctx.req.query?.returnTo)?.trim()\n const result = await getOAuthStartRedirectUrl({\n ctx,\n providerId: resolvedProviderId,\n returnTo,\n authorizationParams: providerAuthorizationParams,\n })\n\n if (!result.success) {\n ctx.res.status(result.statusCode)\n return { success: false, error: result.error }\n }\n\n ctx.res.redirect(result.redirectUrl)\n return { success: true }\n}\n\nexport const createOAuthCallbackHandler = ({\n providerId,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n}: {\n providerId?: string\n createUserOnFirstSignIn?: boolean\n missingUserRedirectPath?: string\n successRedirectPath?: string\n} = {}): ApiHandler<any, { success: boolean; error?: string }, any> => async (\n _payload,\n ctx,\n) => {\n const result = await processOAuthCallback({\n ctx,\n providerId,\n createUserOnFirstSignIn,\n missingUserRedirectPath,\n successRedirectPath,\n })\n\n if (result.type === \"error\") {\n ctx.res.redirect(result.redirectPath)\n return { success: false, error: result.error }\n }\n\n if (result.type === \"missing_user\") {\n if (result.redirectPath) {\n ctx.res.redirect(result.redirectPath)\n } else {\n ctx.res.redirect(\"/auth/sign-up\")\n }\n return { success: false, error: \"user_not_found\" }\n }\n\n ctx.res.redirect(result.redirectPath)\n return { success: true }\n}\n\nconst base64UrlEncode = (input: Buffer | string) =>\n Buffer.from(input)\n .toString(\"base64\")\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/g, \"\")\n\nexport const createAppleClientSecret = ({\n teamId,\n clientId,\n keyId,\n privateKeyPem,\n now = new Date(),\n expiresInSeconds = 10 * 60,\n}: {\n teamId: string\n clientId: string\n keyId: string\n privateKeyPem: string\n now?: Date\n expiresInSeconds?: number\n}) => {\n const teamIdValue = teamId.trim()\n const clientIdValue = clientId.trim()\n const keyIdValue = keyId.trim()\n const privateKeyPemValue = privateKeyPem.trim()\n\n if (!teamIdValue) throw new Error(\"teamId is required\")\n if (!clientIdValue) throw new Error(\"clientId is required\")\n if (!keyIdValue) throw new Error(\"keyId is required\")\n if (!privateKeyPemValue) throw new Error(\"privateKeyPem is required\")\n\n const nowSeconds = Math.floor(now.getTime() / 1000)\n const expiresIn = Number.isFinite(expiresInSeconds) ? expiresInSeconds : 10 * 60\n const exp = nowSeconds + Math.max(60, Math.min(expiresIn, 60 * 60 * 24 * 180))\n\n const header = { alg: \"ES256\", kid: keyIdValue, typ: \"JWT\" }\n const payload = {\n iss: teamIdValue,\n iat: nowSeconds,\n exp,\n aud: \"https://appleid.apple.com\",\n sub: clientIdValue,\n }\n\n const signingInput = `${base64UrlEncode(JSON.stringify(header))}.${base64UrlEncode(JSON.stringify(payload))}`\n const signature = crypto.sign(\"sha256\", Buffer.from(signingInput), {\n key: privateKeyPemValue,\n dsaEncoding: \"ieee-p1363\",\n })\n\n return `${signingInput}.${base64UrlEncode(signature)}`\n}\n"],"names":["isSafeRedirectPath","base64UrlEncode","redirectPath","tenantId"],"mappings":"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"}
|
package/dist/oauth/lib.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../src/oauth/lib.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../../src/oauth/lib.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,cAAc,CAAA;AAyH9C,MAAM,MAAM,gBAAgB,GACxB;IAAE,OAAO,EAAE,IAAI,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GACtC;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAA;AAEzD,eAAO,MAAM,wBAAwB,GAAU,yEAK5C;IACD,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC7C,KAAG,OAAO,CAAC,gBAAgB,CA8E3B,CAAA;AAED,MAAM,MAAM,mBAAmB,GAC3B;IACA,OAAO,EAAE,IAAI,CAAA;IACb,IAAI,EAAE,WAAW,CAAA;IACjB,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,eAAe,EAAE,MAAM,EAAE,CAAA;CAC1B,GACC;IACA,OAAO,EAAE,KAAK,CAAA;IACd,IAAI,EAAE,cAAc,CAAA;IACpB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GACC;IACA,OAAO,EAAE,KAAK,CAAA;IACd,IAAI,EAAE,OAAO,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA;AAKH,eAAO,MAAM,oBAAoB,GAAU,iHAMxC;IACD,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAA;IACb,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,mBAAmB,CAAC,EAAE,MAAM,CAAA;CAC7B,KAAG,OAAO,CAAC,mBAAmB,CAmU9B,CAAA;AAED,eAAO,MAAM,uBAAuB,GAAI,0CAGrC;IACD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,sBAAsB,CAAC,EAAE,CAAC,UAAU,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAA;CAC/E,KAAG,UAAU,CAAC,GAAG,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,CAuBjE,CAAA;AAED,eAAO,MAAM,0BAA0B,GAAI,yFAKxC;IACD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,uBAAuB,CAAC,EAAE,OAAO,CAAA;IACjC,uBAAuB,CAAC,EAAE,MAAM,CAAA;IAChC,mBAAmB,CAAC,EAAE,MAAM,CAAA;CACxB,KAAG,UAAU,CAAC,GAAG,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EAAE,GAAG,CA4BjE,CAAA;AASD,eAAO,MAAM,uBAAuB,GAAI,oEAOrC;IACD,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,MAAM,CAAA;IACrB,GAAG,CAAC,EAAE,IAAI,CAAA;IACV,gBAAgB,CAAC,EAAE,MAAM,CAAA;CAC1B,WA+BA,CAAA"}
|