@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.
@@ -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
- PKCEMethod: "S256",
691
- profileRequest: {
692
- authIn: "header",
693
- encoding: "application/json",
694
- method: "GET",
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: ["id"],
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: "header",
2294
- body: async (config) => {
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
- method: "POST",
2308
- url: "https://wbsapi.withings.net/v2/oauth2"
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
- subjectType: "string",
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 getWithingsProps = async (config) => {
2528
+ var getWithingsSignatureParams = async (config, action) => {
2514
2529
  const timestamp = Math.floor(Date.now() / 1000);
2515
- const signature = `getnonce,${config.clientId},${timestamp}`;
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", hashedSignature);
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
- return {
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
- return;
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: initMigration("sessions", [
3250
- authSessionsTable,
3251
- authUnregisteredSessionsTable
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=C8D20760311031E264756E2164756E21
3515
+ //# debugId=D9CB4120E36FA20E64756E2164756E21
3451
3516
  //# sourceMappingURL=migrate.js.map