@absolutejs/auth 0.57.7 → 0.57.8
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/cli/migrate.js +121 -56
- package/dist/cli/migrate.js.map +5 -5
- package/dist/htmx/index.js +269 -111
- package/dist/htmx/index.js.map +3 -3
- package/dist/index.d.ts +5 -4
- package/dist/index.js +340 -134
- package/dist/index.js.map +11 -11
- package/dist/linkedProviders/index.js +269 -111
- package/dist/linkedProviders/index.js.map +3 -3
- package/dist/providers/clients.d.ts +30 -17
- package/dist/providers/index.js +269 -111
- package/dist/providers/index.js.map +3 -3
- package/dist/routes/profile.d.ts +6 -3
- package/dist/routes/refresh.d.ts +1 -1
- package/dist/routes/revoke.d.ts +1 -1
- package/dist/server.js +340 -134
- package/dist/server.js.map +11 -11
- package/dist/session/neonStore.d.ts +60 -0
- package/dist/types.d.ts +6 -1
- package/dist/utils.d.ts +1 -1
- package/package.json +2 -2
package/dist/cli/migrate.js
CHANGED
|
@@ -685,17 +685,23 @@ var providers = defineProviders({
|
|
|
685
685
|
},
|
|
686
686
|
apple: {
|
|
687
687
|
authorizationUrl: "https://appleid.apple.com/auth/authorize",
|
|
688
|
+
createAuthorizationURLSearchParams: {
|
|
689
|
+
response_mode: "form_post"
|
|
690
|
+
},
|
|
691
|
+
createClientSecret: (config) => createAppleClientSecret(config),
|
|
688
692
|
isOIDC: true,
|
|
689
693
|
isRefreshable: true,
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
url: "https://appleid.apple.com/auth/userinfo"
|
|
694
|
+
revocationRequest: {
|
|
695
|
+
authIn: "body",
|
|
696
|
+
encoding: "application/x-www-form-urlencoded",
|
|
697
|
+
tokenParamName: "token",
|
|
698
|
+
url: "https://appleid.apple.com/auth/revoke"
|
|
696
699
|
},
|
|
697
700
|
scopeRequired: false,
|
|
698
|
-
subject: ["
|
|
701
|
+
subject: ["sub"],
|
|
702
|
+
subjectBySource: {
|
|
703
|
+
idToken: ["sub"]
|
|
704
|
+
},
|
|
699
705
|
subjectType: "string",
|
|
700
706
|
tokenRequest: {
|
|
701
707
|
authIn: "body",
|
|
@@ -764,6 +770,7 @@ var providers = defineProviders({
|
|
|
764
770
|
token_type_hint: "refresh_token"
|
|
765
771
|
}),
|
|
766
772
|
encoding: "application/json",
|
|
773
|
+
inputSource: "refreshToken",
|
|
767
774
|
tokenParamName: "token",
|
|
768
775
|
url: (config) => `https://${config.domain}/oauth/revoke`
|
|
769
776
|
},
|
|
@@ -1895,6 +1902,7 @@ var providers = defineProviders({
|
|
|
1895
1902
|
token_type_hint: "refresh_token"
|
|
1896
1903
|
}),
|
|
1897
1904
|
encoding: "application/json",
|
|
1905
|
+
inputSource: "refreshToken",
|
|
1898
1906
|
url: "https://www.reddit.com/api/v1/revoke_token"
|
|
1899
1907
|
},
|
|
1900
1908
|
scopeRequired: true,
|
|
@@ -2268,49 +2276,27 @@ var providers = defineProviders({
|
|
|
2268
2276
|
authorizationUrl: "https://account.withings.com/oauth2_user/authorize2",
|
|
2269
2277
|
isOIDC: false,
|
|
2270
2278
|
isRefreshable: true,
|
|
2271
|
-
profileRequest: {
|
|
2272
|
-
authIn: "header",
|
|
2273
|
-
body: async (config) => {
|
|
2274
|
-
const props = await getWithingsProps(config);
|
|
2275
|
-
if (props === undefined)
|
|
2276
|
-
throw new Error("Failed to get Withings search properties");
|
|
2277
|
-
const { nonce, hashedSignature } = props;
|
|
2278
|
-
return [
|
|
2279
|
-
["action", "getuser"],
|
|
2280
|
-
["nonce", nonce],
|
|
2281
|
-
["client_id", config.clientId],
|
|
2282
|
-
["signature", hashedSignature]
|
|
2283
|
-
];
|
|
2284
|
-
},
|
|
2285
|
-
encoding: "application/x-www-form-urlencoded",
|
|
2286
|
-
method: "POST",
|
|
2287
|
-
url: "https://wbsapi.withings.net/v2/oauth2"
|
|
2288
|
-
},
|
|
2289
2279
|
refreshAccessTokenBody: {
|
|
2290
2280
|
action: "requesttoken"
|
|
2291
2281
|
},
|
|
2292
2282
|
revocationRequest: {
|
|
2293
|
-
authIn: "
|
|
2294
|
-
body:
|
|
2295
|
-
const props = await getWithingsProps(config);
|
|
2296
|
-
if (!props)
|
|
2297
|
-
throw new Error("Failed to get Withings props");
|
|
2298
|
-
const { nonce, hashedSignature } = props;
|
|
2299
|
-
return [
|
|
2300
|
-
["action", "revoke"],
|
|
2301
|
-
["client_id", config.clientId],
|
|
2302
|
-
["nonce", nonce],
|
|
2303
|
-
["signature", hashedSignature]
|
|
2304
|
-
];
|
|
2305
|
-
},
|
|
2283
|
+
authIn: "body",
|
|
2284
|
+
body: (config) => getWithingsSignatureParams(config, "revoke"),
|
|
2306
2285
|
encoding: "application/x-www-form-urlencoded",
|
|
2307
|
-
|
|
2308
|
-
|
|
2286
|
+
includeClientCredentials: false,
|
|
2287
|
+
inputSource: "subject",
|
|
2288
|
+
inputType: "number",
|
|
2289
|
+
tokenParamName: "userid",
|
|
2290
|
+
url: "https://wbsapi.withings.net/v2/oauth2",
|
|
2291
|
+
validateResponse: (value) => assertWithingsSuccess(value)
|
|
2309
2292
|
},
|
|
2310
2293
|
scopeDelimiter: ",",
|
|
2311
2294
|
scopeRequired: true,
|
|
2312
2295
|
subject: ["userid"],
|
|
2313
|
-
|
|
2296
|
+
subjectBySource: {
|
|
2297
|
+
tokenResponse: ["body", "userid"]
|
|
2298
|
+
},
|
|
2299
|
+
subjectType: "number",
|
|
2314
2300
|
tokenRequest: {
|
|
2315
2301
|
authIn: "body",
|
|
2316
2302
|
encoding: "application/x-www-form-urlencoded",
|
|
@@ -2469,6 +2455,7 @@ var providers = defineProviders({
|
|
|
2469
2455
|
}
|
|
2470
2456
|
}
|
|
2471
2457
|
});
|
|
2458
|
+
var isObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && Object.prototype.toString.call(value) === "[object Object]";
|
|
2472
2459
|
var isOIDCProviderOption = (option) => {
|
|
2473
2460
|
if (!isValidProviderOption(option))
|
|
2474
2461
|
return false;
|
|
@@ -2481,6 +2468,12 @@ var isPKCEProviderOption = (option) => {
|
|
|
2481
2468
|
const provider = providers[option];
|
|
2482
2469
|
return provider.PKCEMethod !== undefined;
|
|
2483
2470
|
};
|
|
2471
|
+
var isProfileProviderOption = (option) => {
|
|
2472
|
+
if (!isValidProviderOption(option))
|
|
2473
|
+
return false;
|
|
2474
|
+
const provider = providers[option];
|
|
2475
|
+
return provider.profileRequest !== undefined;
|
|
2476
|
+
};
|
|
2484
2477
|
var isRefreshableProviderOption = (option) => {
|
|
2485
2478
|
if (!isValidProviderOption(option))
|
|
2486
2479
|
return false;
|
|
@@ -2500,6 +2493,28 @@ var isScopeRequiredProviderOption = (option) => {
|
|
|
2500
2493
|
return provider.scopeRequired;
|
|
2501
2494
|
};
|
|
2502
2495
|
var isValidProviderOption = (option) => Object.hasOwn(providers, option);
|
|
2496
|
+
var assertWithingsSuccess = (value) => {
|
|
2497
|
+
if (!isObject(value) || value.status !== 0) {
|
|
2498
|
+
const status = isObject(value) ? value.status : "invalid response";
|
|
2499
|
+
const detail = isObject(value) && typeof value.error === "string" ? `: ${value.error}` : "";
|
|
2500
|
+
throw new Error(`Withings request failed (${String(status)})${detail}`);
|
|
2501
|
+
}
|
|
2502
|
+
};
|
|
2503
|
+
var createOAuth2FetchError = async (response) => {
|
|
2504
|
+
const clone = response.clone();
|
|
2505
|
+
const prefix = `HTTP ${response.status} ${response.statusText} for ${response.url}`;
|
|
2506
|
+
const payload = await response.json().catch(() => null);
|
|
2507
|
+
if (payload && typeof payload === "object" && Object.keys(payload).length) {
|
|
2508
|
+
return new Error(`${prefix}
|
|
2509
|
+
${JSON.stringify(payload)}`);
|
|
2510
|
+
}
|
|
2511
|
+
const text3 = await clone.text().catch(() => "");
|
|
2512
|
+
if (text3) {
|
|
2513
|
+
return new Error(`${prefix}
|
|
2514
|
+
${text3}`);
|
|
2515
|
+
}
|
|
2516
|
+
return new Error(prefix);
|
|
2517
|
+
};
|
|
2503
2518
|
var encodeBase64 = (input) => {
|
|
2504
2519
|
let raw;
|
|
2505
2520
|
if (typeof input === "string") {
|
|
@@ -2510,25 +2525,31 @@ var encodeBase64 = (input) => {
|
|
|
2510
2525
|
}
|
|
2511
2526
|
return btoa(raw);
|
|
2512
2527
|
};
|
|
2513
|
-
var
|
|
2528
|
+
var getWithingsSignatureParams = async (config, action) => {
|
|
2514
2529
|
const timestamp = Math.floor(Date.now() / 1000);
|
|
2515
|
-
const
|
|
2516
|
-
const hashedSignature = await hmacSha256(signature, config.clientSecret);
|
|
2530
|
+
const nonceSignature = await hmacSha256(`getnonce,${config.clientId},${timestamp}`, config.clientSecret);
|
|
2517
2531
|
const nonceUrl = new URL("https://wbsapi.withings.net/v2/signature");
|
|
2518
2532
|
nonceUrl.searchParams.set("action", "getnonce");
|
|
2519
2533
|
nonceUrl.searchParams.set("client_id", config.clientId);
|
|
2520
2534
|
nonceUrl.searchParams.set("timestamp", timestamp.toString());
|
|
2521
|
-
nonceUrl.searchParams.set("signature",
|
|
2535
|
+
nonceUrl.searchParams.set("signature", nonceSignature);
|
|
2522
2536
|
const nonceTarget = nonceUrl.toString();
|
|
2523
2537
|
const nonceResponse = await fetch(nonceTarget, { method: "POST" });
|
|
2538
|
+
if (!nonceResponse.ok) {
|
|
2539
|
+
throw await createOAuth2FetchError(nonceResponse);
|
|
2540
|
+
}
|
|
2524
2541
|
const nonceData = await nonceResponse.json();
|
|
2525
|
-
if (nonceData.status === 0) {
|
|
2526
|
-
|
|
2527
|
-
hashedSignature,
|
|
2528
|
-
nonce: nonceData.body.nonce
|
|
2529
|
-
};
|
|
2542
|
+
if (!isObject(nonceData) || nonceData.status !== 0 || !isObject(nonceData.body) || typeof nonceData.body.nonce !== "string" || nonceData.body.nonce.length === 0) {
|
|
2543
|
+
throw new Error("Withings returned an invalid nonce response");
|
|
2530
2544
|
}
|
|
2531
|
-
|
|
2545
|
+
const { nonce } = nonceData.body;
|
|
2546
|
+
const signature = await hmacSha256(`${action},${config.clientId},${nonce}`, config.clientSecret);
|
|
2547
|
+
return {
|
|
2548
|
+
action,
|
|
2549
|
+
client_id: config.clientId,
|
|
2550
|
+
nonce,
|
|
2551
|
+
signature
|
|
2552
|
+
};
|
|
2532
2553
|
};
|
|
2533
2554
|
var hmacSha256 = async (message, secret) => {
|
|
2534
2555
|
const encoder = new TextEncoder;
|
|
@@ -2536,6 +2557,13 @@ var hmacSha256 = async (message, secret) => {
|
|
|
2536
2557
|
const sigBuffer = await crypto.subtle.sign("HMAC", key, encoder.encode(message));
|
|
2537
2558
|
return Array.from(new Uint8Array(sigBuffer)).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
2538
2559
|
};
|
|
2560
|
+
var DAYS_IN_APPLE_CLIENT_SECRET_LIFETIME = 180;
|
|
2561
|
+
var HOURS_PER_DAY = 24;
|
|
2562
|
+
var MINUTES_PER_HOUR = 60;
|
|
2563
|
+
var SECONDS_PER_MINUTE = 60;
|
|
2564
|
+
var APPLE_CLIENT_SECRET_LIFETIME_SECONDS = SECONDS_PER_MINUTE * MINUTES_PER_HOUR * HOURS_PER_DAY * DAYS_IN_APPLE_CLIENT_SECRET_LIFETIME;
|
|
2565
|
+
var APPLE_ISSUER = "https://appleid.apple.com";
|
|
2566
|
+
var MILLISECONDS_PER_SECOND = 1000;
|
|
2539
2567
|
var createRandomBase64UrlGenerator = (length) => () => {
|
|
2540
2568
|
const buffer = crypto.getRandomValues(new Uint8Array(length));
|
|
2541
2569
|
return base64Url(buffer);
|
|
@@ -2543,8 +2571,29 @@ var createRandomBase64UrlGenerator = (length) => () => {
|
|
|
2543
2571
|
var generateCodeVerifier = createRandomBase64UrlGenerator(NUM_GENERATOR_BYTES);
|
|
2544
2572
|
var generateState = createRandomBase64UrlGenerator(NUM_GENERATOR_BYTES);
|
|
2545
2573
|
var base64Url = (input) => encodeBase64(input).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
2574
|
+
var encodeJwtPart = (value) => base64Url(new TextEncoder().encode(JSON.stringify(value)));
|
|
2575
|
+
var createAppleClientSecret = async (credentials) => {
|
|
2576
|
+
const issuedAt = Math.floor(Date.now() / MILLISECONDS_PER_SECOND);
|
|
2577
|
+
const header = encodeJwtPart({
|
|
2578
|
+
alg: "ES256",
|
|
2579
|
+
kid: credentials.keyId,
|
|
2580
|
+
typ: "JWT"
|
|
2581
|
+
});
|
|
2582
|
+
const payload = encodeJwtPart({
|
|
2583
|
+
aud: APPLE_ISSUER,
|
|
2584
|
+
exp: issuedAt + APPLE_CLIENT_SECRET_LIFETIME_SECONDS,
|
|
2585
|
+
iat: issuedAt,
|
|
2586
|
+
iss: credentials.teamId,
|
|
2587
|
+
sub: credentials.clientId
|
|
2588
|
+
});
|
|
2589
|
+
const signingInput = `${header}.${payload}`;
|
|
2590
|
+
const privateKey = await crypto.subtle.importKey("pkcs8", Uint8Array.from(credentials.pkcs8PrivateKey), { name: "ECDSA", namedCurve: "P-256" }, false, ["sign"]);
|
|
2591
|
+
const signature = await crypto.subtle.sign({ hash: "SHA-256", name: "ECDSA" }, privateKey, new TextEncoder().encode(signingInput));
|
|
2592
|
+
return `${signingInput}.${base64Url(signature)}`;
|
|
2593
|
+
};
|
|
2546
2594
|
var oidcProviderOptions = Object.keys(providers).filter(isOIDCProviderOption);
|
|
2547
2595
|
var pkceProviderOptions = Object.keys(providers).filter(isPKCEProviderOption);
|
|
2596
|
+
var profileProviderOptions = Object.keys(providers).filter(isProfileProviderOption);
|
|
2548
2597
|
var providerOptions = Object.keys(providers).filter(isValidProviderOption);
|
|
2549
2598
|
var refreshableProviderOptions = Object.keys(providers).filter(isRefreshableProviderOption);
|
|
2550
2599
|
var revocableProviderOptions = Object.keys(providers).filter(isRevocableProviderOption);
|
|
@@ -2893,6 +2942,7 @@ var authSessionsTable = pgTable16("auth_sessions", {
|
|
|
2893
2942
|
created_at: timestamp2("created_at").notNull().defaultNow(),
|
|
2894
2943
|
expires_at_ms: bigint14("expires_at_ms", { mode: "number" }).notNull(),
|
|
2895
2944
|
id: varchar16("id", { length: 255 }).primaryKey(),
|
|
2945
|
+
oauth_subject_json: jsonb8("oauth_subject_json").$type(),
|
|
2896
2946
|
refresh_token: text6("refresh_token"),
|
|
2897
2947
|
updated_at: timestamp2("updated_at").notNull().defaultNow(),
|
|
2898
2948
|
user_json: jsonb8("user_json").$type().notNull()
|
|
@@ -2902,6 +2952,7 @@ var authUnregisteredSessionsTable = pgTable16("auth_unregistered_sessions", {
|
|
|
2902
2952
|
created_at: timestamp2("created_at").notNull().defaultNow(),
|
|
2903
2953
|
expires_at_ms: bigint14("expires_at_ms", { mode: "number" }).notNull(),
|
|
2904
2954
|
id: varchar16("id", { length: 255 }).primaryKey(),
|
|
2955
|
+
oauth_subject_json: jsonb8("oauth_subject_json").$type(),
|
|
2905
2956
|
refresh_token: text6("refresh_token"),
|
|
2906
2957
|
session_information_json: jsonb8("session_information_json").$type(),
|
|
2907
2958
|
updated_at: timestamp2("updated_at").notNull().defaultNow(),
|
|
@@ -3178,6 +3229,14 @@ var oidcResourceAudienceMigration = {
|
|
|
3178
3229
|
].join(`
|
|
3179
3230
|
`)
|
|
3180
3231
|
};
|
|
3232
|
+
var sessionOAuthSubjectMigration = {
|
|
3233
|
+
id: "0002_oauth_subject",
|
|
3234
|
+
sql: [
|
|
3235
|
+
'ALTER TABLE "auth_sessions" ADD COLUMN IF NOT EXISTS "oauth_subject_json" jsonb;',
|
|
3236
|
+
'ALTER TABLE "auth_unregistered_sessions" ADD COLUMN IF NOT EXISTS "oauth_subject_json" jsonb;'
|
|
3237
|
+
].join(`
|
|
3238
|
+
`)
|
|
3239
|
+
};
|
|
3181
3240
|
var blockMigrations = {
|
|
3182
3241
|
adaptive: initMigration("adaptive", [knownDevicesTable, loginHistoryTable]),
|
|
3183
3242
|
agents: {
|
|
@@ -3246,10 +3305,16 @@ var blockMigrations = {
|
|
|
3246
3305
|
portal: initMigration("portal", [setupSessionsTable]),
|
|
3247
3306
|
roles: initMigration("roles", [rolesTable]),
|
|
3248
3307
|
scim: initMigration("scim", [scimTokensTable]),
|
|
3249
|
-
sessions:
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3308
|
+
sessions: {
|
|
3309
|
+
block: "sessions",
|
|
3310
|
+
migrations: [
|
|
3311
|
+
...initMigration("sessions", [
|
|
3312
|
+
authSessionsTable,
|
|
3313
|
+
authUnregisteredSessionsTable
|
|
3314
|
+
]).migrations,
|
|
3315
|
+
sessionOAuthSubjectMigration
|
|
3316
|
+
]
|
|
3317
|
+
},
|
|
3253
3318
|
sso: initMigration("sso", [ssoConnectionsTable, samlServiceProvidersTable]),
|
|
3254
3319
|
vault: initMigration("vault", [vaultEntriesTable]),
|
|
3255
3320
|
vc: initMigration("vc", [
|
|
@@ -3447,5 +3512,5 @@ var main = async () => {
|
|
|
3447
3512
|
};
|
|
3448
3513
|
await main();
|
|
3449
3514
|
|
|
3450
|
-
//# debugId=
|
|
3515
|
+
//# debugId=D9CB4120E36FA20E64756E2164756E21
|
|
3451
3516
|
//# sourceMappingURL=migrate.js.map
|