@absolutejs/auth 0.29.3 → 0.30.0-beta.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/dist/index.d.ts CHANGED
@@ -13458,6 +13458,9 @@ export declare const auth: <UserType>({ providersConfiguration, authorizeRoute,
13458
13458
  acr_values?: string | undefined;
13459
13459
  code_challenge?: string | undefined;
13460
13460
  code_challenge_method?: string | undefined;
13461
+ id_token_hint?: string | undefined;
13462
+ max_age?: string | undefined;
13463
+ prompt?: string | undefined;
13461
13464
  request_uri?: string | undefined;
13462
13465
  response_type?: string | undefined;
13463
13466
  state?: string | undefined;
@@ -13667,8 +13670,8 @@ export declare const auth: <UserType>({ providersConfiguration, authorizeRoute,
13667
13670
  params: {};
13668
13671
  query: {
13669
13672
  client_id?: string | undefined;
13670
- state?: string | undefined;
13671
13673
  id_token_hint?: string | undefined;
13674
+ state?: string | undefined;
13672
13675
  post_logout_redirect_uri?: string | undefined;
13673
13676
  };
13674
13677
  headers: unknown;
@@ -13691,8 +13694,8 @@ export declare const auth: <UserType>({ providersConfiguration, authorizeRoute,
13691
13694
  post: {
13692
13695
  body: {
13693
13696
  client_id?: string | undefined;
13694
- state?: string | undefined;
13695
13697
  id_token_hint?: string | undefined;
13698
+ state?: string | undefined;
13696
13699
  post_logout_redirect_uri?: string | undefined;
13697
13700
  };
13698
13701
  params: {};
@@ -13832,6 +13835,54 @@ export declare const auth: <UserType>({ providersConfiguration, authorizeRoute,
13832
13835
  };
13833
13836
  };
13834
13837
  };
13838
+ } & {
13839
+ [x: string]: {
13840
+ get: {
13841
+ body: unknown;
13842
+ params: {};
13843
+ query: unknown;
13844
+ headers: {
13845
+ authorization?: string | undefined;
13846
+ };
13847
+ response: {
13848
+ 200: Response;
13849
+ 422: {
13850
+ type: "validation";
13851
+ on: string;
13852
+ summary?: string;
13853
+ message?: string;
13854
+ found?: unknown;
13855
+ property?: string;
13856
+ expected?: string;
13857
+ };
13858
+ };
13859
+ };
13860
+ };
13861
+ } & {
13862
+ [x: string]: {
13863
+ post: {
13864
+ body: {
13865
+ access_token?: string | undefined;
13866
+ };
13867
+ params: {};
13868
+ query: unknown;
13869
+ headers: {
13870
+ authorization?: string | undefined;
13871
+ };
13872
+ response: {
13873
+ 200: Response;
13874
+ 422: {
13875
+ type: "validation";
13876
+ on: string;
13877
+ summary?: string;
13878
+ message?: string;
13879
+ found?: unknown;
13880
+ property?: string;
13881
+ expected?: string;
13882
+ };
13883
+ };
13884
+ };
13885
+ };
13835
13886
  } & {
13836
13887
  [x: string]: {
13837
13888
  get: {
@@ -15067,6 +15118,8 @@ export type { DpopResult } from './oidc/dpop';
15067
15118
  export { CLIENT_ASSERTION_TYPE, verifyClientAssertion } from './oidc/clientAuth';
15068
15119
  export { createInMemoryAuthorizationCodeStore, createInMemoryClientAssertionJtiStore, createInMemoryClientRegistrationTokenStore, createInMemoryDeviceAuthorizationStore, createInMemoryInitialAccessTokenStore, createInMemoryLogoutDeliveryStore, createInMemoryOAuthClientStore, createInMemoryOidcRefreshTokenStore, createInMemoryPushedAuthorizationRequestStore } from './oidc/inMemoryStores';
15069
15120
  export { consumePushedRequest, pushAuthorizationRequest, DEFAULT_PAR_TTL_MS, REQUEST_URI_PREFIX } from './oidc/par';
15121
+ export { fetchUserInfo, readUserInfoBearer, userInfoChallengeHeader } from './oidc/userinfo';
15122
+ export type { UserInfoResult } from './oidc/userinfo';
15070
15123
  export { fanOutBackchannelLogout, mintLogoutToken, resolvePostLogoutRedirect, verifyIdTokenHint } from './oidc/logout';
15071
15124
  export { createNeonAuthorizationCodeStore, createNeonClientAssertionJtiStore, createNeonClientRegistrationTokenStore, createNeonDeviceAuthorizationStore, createNeonInitialAccessTokenStore, createNeonLogoutDeliveryStore, createNeonOAuthClientStore, createNeonOidcRefreshTokenStore, createNeonPushedAuthorizationRequestStore, createPostgresAuthorizationCodeStore, createPostgresClientAssertionJtiStore, createPostgresClientRegistrationTokenStore, createPostgresDeviceAuthorizationStore, createPostgresInitialAccessTokenStore, createPostgresLogoutDeliveryStore, createPostgresOAuthClientStore, createPostgresOidcRefreshTokenStore, createPostgresPushedAuthorizationRequestStore, oauthClientAssertionJtisTable, oauthClientRegistrationTokensTable, oauthClientsTable, oauthCodesTable, oauthDeviceAuthorizationsTable, oauthInitialAccessTokensTable, oauthLogoutDeliveriesTable, oauthPushedAuthorizationRequestsTable, oauthRefreshTokensTable } from './oidc/postgresStores';
15072
15125
  export { deleteRegisteredClient, getRegisteredClient, registerClient, updateRegisteredClient, type ClientRegistrationDecision, type ClientRegistrationMetadata, type OnClientRegistration, type RegisterClientResult } from './oidc/registration';
package/dist/index.js CHANGED
@@ -4843,6 +4843,51 @@ var pushAuthorizationRequest = async ({
4843
4843
  };
4844
4844
  };
4845
4845
 
4846
+ // src/oidc/userinfo.ts
4847
+ var BEARER_PREFIX2 = "Bearer ";
4848
+ var readBearer = (authorization) => {
4849
+ if (authorization === undefined || !authorization.startsWith(BEARER_PREFIX2)) {
4850
+ return;
4851
+ }
4852
+ return authorization.slice(BEARER_PREFIX2.length).trim();
4853
+ };
4854
+ var readUserInfoBearer = readBearer;
4855
+ var fetchUserInfo = async ({
4856
+ config,
4857
+ now = Date.now(),
4858
+ token
4859
+ }) => {
4860
+ if (token === undefined) {
4861
+ return {
4862
+ body: { error: "invalid_request" },
4863
+ error: "invalid_request",
4864
+ ok: false
4865
+ };
4866
+ }
4867
+ const verified = await verifyJwt(token, config.signingKey.publicJwk);
4868
+ if (verified === undefined) {
4869
+ return {
4870
+ body: { error: "invalid_token" },
4871
+ error: "invalid_token",
4872
+ ok: false
4873
+ };
4874
+ }
4875
+ const { payload } = verified;
4876
+ if (typeof payload.sub !== "string" || typeof payload.exp !== "number" || payload.exp * 1000 <= now) {
4877
+ return {
4878
+ body: { error: "invalid_token" },
4879
+ error: "invalid_token",
4880
+ ok: false
4881
+ };
4882
+ }
4883
+ const enriched = await config.getUserInfo?.(payload.sub);
4884
+ return {
4885
+ body: { ...enriched ?? {}, sub: payload.sub },
4886
+ ok: true
4887
+ };
4888
+ };
4889
+ var userInfoChallengeHeader = (error) => `Bearer realm="userinfo", error="${error}"`;
4890
+
4846
4891
  // src/oidc/registration.ts
4847
4892
  var REG_TOKEN_BYTES = 32;
4848
4893
  var CLIENT_ID_BYTES = 16;
@@ -5106,6 +5151,7 @@ var oidcProviderRoutes = (config) => {
5106
5151
  const endSessionRoute = `${oidcRoute}/end_session`;
5107
5152
  const parRoute = `${oidcRoute}/par`;
5108
5153
  const registrationRoute = `${oidcRoute}/register`;
5154
+ const userinfoRoute = `${oidcRoute}/userinfo`;
5109
5155
  const registrationBaseUrl = `${issuer}${registrationRoute}`;
5110
5156
  const tokenUrl = `${issuer}${oidcRoute}/token`;
5111
5157
  const authenticateClient = async (clientId, clientSecret) => {
@@ -5317,7 +5363,8 @@ var oidcProviderRoutes = (config) => {
5317
5363
  "none",
5318
5364
  "private_key_jwt"
5319
5365
  ],
5320
- token_endpoint_auth_signing_alg_values_supported: ["ES256"]
5366
+ token_endpoint_auth_signing_alg_values_supported: ["ES256"],
5367
+ userinfo_endpoint: `${issuer}${userinfoRoute}`
5321
5368
  };
5322
5369
  if (config.deviceAuthorizationStore) {
5323
5370
  discovery.device_authorization_endpoint = `${issuer}${deviceAuthorizationRoute}`;
@@ -5422,7 +5469,21 @@ var oidcProviderRoutes = (config) => {
5422
5469
  session: store.session,
5423
5470
  userSessionId: user_session_id.value
5424
5471
  });
5425
- if (userSession === undefined) {
5472
+ const promptValues = effectiveQuery.prompt === undefined ? [] : effectiveQuery.prompt.split(" ");
5473
+ const wantsSilent = promptValues.includes("none");
5474
+ const wantsLogin = promptValues.includes("login") || promptValues.includes("consent");
5475
+ const maxAge = effectiveQuery.max_age === undefined ? undefined : Number(effectiveQuery.max_age);
5476
+ const sessionStaleByMaxAge = userSession !== undefined && maxAge !== undefined && !Number.isNaN(maxAge) && maxAge >= 0 && (userSession.authenticatedAt ?? 0) < Date.now() - maxAge * 1000;
5477
+ const hintSub = effectiveQuery.id_token_hint === undefined ? undefined : (await verifyIdTokenHint({
5478
+ config,
5479
+ idTokenHint: effectiveQuery.id_token_hint
5480
+ }))?.sub;
5481
+ const hintMismatch = userSession !== undefined && hintSub !== undefined && hintSub !== getUserId(userSession.user);
5482
+ const needsReauth = wantsLogin || sessionStaleByMaxAge || hintMismatch;
5483
+ if (userSession === undefined || needsReauth) {
5484
+ if (wantsSilent) {
5485
+ return errorRedirect(userSession === undefined ? "login_required" : "interaction_required");
5486
+ }
5426
5487
  return loginUrl === undefined ? jsonResponse({ error: "login_required" }, HTTP_UNAUTHORIZED2) : redirectTo(`${loginUrl}?return_to=${encodeURIComponent(request.url)}`);
5427
5488
  }
5428
5489
  const requested = scope === undefined || scope.length === 0 ? client.scopes : scope.split(" ").filter((entry) => client.scopes.includes(entry));
@@ -5472,7 +5533,10 @@ var oidcProviderRoutes = (config) => {
5472
5533
  client_id: t12.Optional(t12.String()),
5473
5534
  code_challenge: t12.Optional(t12.String()),
5474
5535
  code_challenge_method: t12.Optional(t12.String()),
5536
+ id_token_hint: t12.Optional(t12.String()),
5537
+ max_age: t12.Optional(t12.String()),
5475
5538
  nonce: t12.Optional(t12.String()),
5539
+ prompt: t12.Optional(t12.String()),
5476
5540
  redirect_uri: t12.Optional(t12.String()),
5477
5541
  request_uri: t12.Optional(t12.String()),
5478
5542
  response_type: t12.Optional(t12.String()),
@@ -5813,6 +5877,43 @@ var oidcProviderRoutes = (config) => {
5813
5877
  authorization: t12.Optional(t12.String())
5814
5878
  }),
5815
5879
  params: t12.Object({ clientId: t12.String() })
5880
+ }).get(userinfoRoute, async ({ headers }) => {
5881
+ const token = readUserInfoBearer(headers.authorization);
5882
+ const result = await fetchUserInfo({ config, token });
5883
+ if (!result.ok) {
5884
+ return new Response(JSON.stringify(result.body), {
5885
+ headers: {
5886
+ "content-type": "application/json",
5887
+ "www-authenticate": userInfoChallengeHeader(result.error)
5888
+ },
5889
+ status: HTTP_UNAUTHORIZED2
5890
+ });
5891
+ }
5892
+ return jsonResponse(result.body, HTTP_OK2);
5893
+ }, {
5894
+ headers: t12.Object({
5895
+ authorization: t12.Optional(t12.String())
5896
+ })
5897
+ }).post(userinfoRoute, async ({ headers, body }) => {
5898
+ const token = readUserInfoBearer(headers.authorization) ?? body.access_token;
5899
+ const result = await fetchUserInfo({ config, token });
5900
+ if (!result.ok) {
5901
+ return new Response(JSON.stringify(result.body), {
5902
+ headers: {
5903
+ "content-type": "application/json",
5904
+ "www-authenticate": userInfoChallengeHeader(result.error)
5905
+ },
5906
+ status: HTTP_UNAUTHORIZED2
5907
+ });
5908
+ }
5909
+ return jsonResponse(result.body, HTTP_OK2);
5910
+ }, {
5911
+ body: t12.Object({
5912
+ access_token: t12.Optional(t12.String())
5913
+ }),
5914
+ headers: t12.Object({
5915
+ authorization: t12.Optional(t12.String())
5916
+ })
5816
5917
  }).get(jwksRoute, () => ({ keys: [toPublicJwk(signingKey)] })).get("/.well-known/openid-configuration", () => discovery);
5817
5918
  };
5818
5919
 
@@ -6314,7 +6415,7 @@ import { Elysia as Elysia18, t as t15 } from "elysia";
6314
6415
  // src/scim/config.ts
6315
6416
  var DEFAULT_SCIM_ROUTE = "/scim/v2";
6316
6417
  var SCIM_TOKEN_BYTES = 32;
6317
- var BEARER_PREFIX2 = "Bearer ";
6418
+ var BEARER_PREFIX3 = "Bearer ";
6318
6419
  var createScimToken = async (scimTokenStore, organizationId) => {
6319
6420
  const token = generateSecureToken(SCIM_TOKEN_BYTES);
6320
6421
  const record = {
@@ -6327,10 +6428,10 @@ var createScimToken = async (scimTokenStore, organizationId) => {
6327
6428
  return { token, tokenId: record.tokenId };
6328
6429
  };
6329
6430
  var resolveScimOrganization = async (scimTokenStore, authorization) => {
6330
- if (authorization === undefined || !authorization.startsWith(BEARER_PREFIX2)) {
6431
+ if (authorization === undefined || !authorization.startsWith(BEARER_PREFIX3)) {
6331
6432
  return;
6332
6433
  }
6333
- const token = authorization.slice(BEARER_PREFIX2.length).trim();
6434
+ const token = authorization.slice(BEARER_PREFIX3.length).trim();
6334
6435
  if (token.length === 0)
6335
6436
  return;
6336
6437
  const record = await scimTokenStore.findByHashedToken(await hashToken(token));
@@ -6347,7 +6448,7 @@ var DEFAULT_PORTAL_ROUTE = "/auth/portal";
6347
6448
  var DEFAULT_SETUP_SESSION_TTL_MS = MILLISECONDS_IN_A_DAY * SETUP_TTL_DAYS;
6348
6449
 
6349
6450
  // src/portal/operations.ts
6350
- var BEARER_PREFIX3 = "Bearer ";
6451
+ var BEARER_PREFIX4 = "Bearer ";
6351
6452
  var createSetupSession = async ({
6352
6453
  capabilities,
6353
6454
  createdBy,
@@ -6373,10 +6474,10 @@ var resolveSetupSession = async ({
6373
6474
  authorization,
6374
6475
  setupSessionStore
6375
6476
  }) => {
6376
- if (authorization === undefined || !authorization.startsWith(BEARER_PREFIX3)) {
6477
+ if (authorization === undefined || !authorization.startsWith(BEARER_PREFIX4)) {
6377
6478
  return;
6378
6479
  }
6379
- const token = authorization.slice(BEARER_PREFIX3.length).trim();
6480
+ const token = authorization.slice(BEARER_PREFIX4.length).trim();
6380
6481
  if (token.length === 0)
6381
6482
  return;
6382
6483
  const session = await setupSessionStore.getSetupSessionByTokenHash(await hashToken(token));
@@ -22904,6 +23005,7 @@ export {
22904
23005
  validateSession,
22905
23006
  validateEmailDeliverability,
22906
23007
  userSessionIdTypebox,
23008
+ userInfoChallengeHeader,
22907
23009
  updateRegisteredClient,
22908
23010
  trustDevice,
22909
23011
  toPublicJwk,
@@ -22945,6 +23047,7 @@ export {
22945
23047
  registerClient,
22946
23048
  refreshableProviderOptions,
22947
23049
  recordLoginAttempt,
23050
+ readUserInfoBearer,
22948
23051
  readSessionRing,
22949
23052
  pushAuthorizationRequest,
22950
23053
  providers,
@@ -23023,6 +23126,7 @@ export {
23023
23126
  generateEncryptionKey,
23024
23127
  generateBackupCodes,
23025
23128
  fingerprintDevice,
23129
+ fetchUserInfo,
23026
23130
  fanOutBackchannelLogout,
23027
23131
  extractPropFromIdentity,
23028
23132
  extractDpopNonceClaim,
@@ -23226,5 +23330,5 @@ export {
23226
23330
  AuthIdentityConflictError
23227
23331
  };
23228
23332
 
23229
- //# debugId=A629114DF39943A964756E2164756E21
23333
+ //# debugId=BAAEA91F75FEB49E64756E2164756E21
23230
23334
  //# sourceMappingURL=index.js.map