@absolutejs/auth 0.27.0 → 0.28.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.js CHANGED
@@ -4297,6 +4297,160 @@ var mcpProtectedResourceMetadata = ({
4297
4297
  scopes_supported: scopes ?? []
4298
4298
  });
4299
4299
  var verifyPkce = async (codeVerifier, codeChallenge) => await hashToken(codeVerifier) === codeChallenge;
4300
+ var inactive = { active: false };
4301
+ var introspectToken = async ({
4302
+ config,
4303
+ hint,
4304
+ now = Date.now(),
4305
+ token
4306
+ }) => {
4307
+ if (hint !== "refresh_token") {
4308
+ const verified = await verifyJwt(token, config.signingKey.publicJwk);
4309
+ const payload = verified?.payload;
4310
+ if (payload !== undefined && typeof payload.sub === "string" && typeof payload.exp === "number" && payload.exp > nowSeconds(now)) {
4311
+ return {
4312
+ active: true,
4313
+ client_id: typeof payload.client_id === "string" ? payload.client_id : "",
4314
+ exp: payload.exp,
4315
+ iat: typeof payload.iat === "number" ? payload.iat : 0,
4316
+ scope: typeof payload.scope === "string" ? payload.scope : "",
4317
+ sub: payload.sub,
4318
+ token_type: "access_token"
4319
+ };
4320
+ }
4321
+ }
4322
+ if (hint !== "access_token") {
4323
+ const refresh = await config.refreshTokenStore.getToken(await hashToken(token));
4324
+ if (refresh && refresh.expiresAt > now) {
4325
+ return {
4326
+ active: true,
4327
+ client_id: refresh.clientId,
4328
+ exp: nowSeconds(refresh.expiresAt),
4329
+ iat: nowSeconds(refresh.createdAt),
4330
+ scope: refresh.scopes.join(" "),
4331
+ sub: refresh.userId,
4332
+ token_type: "refresh_token"
4333
+ };
4334
+ }
4335
+ }
4336
+ return inactive;
4337
+ };
4338
+ var revokeRefreshToken = async (config, token) => {
4339
+ const consumed = await config.refreshTokenStore.consumeToken(await hashToken(token));
4340
+ return consumed !== undefined;
4341
+ };
4342
+ var DEVICE_CODE_BYTES = 32;
4343
+ var USER_CODE_HALF_LENGTH = 4;
4344
+ var USER_CODE_ALPHABET = "BCDFGHJKLMNPQRSTVWXZ23456789";
4345
+ var DEFAULT_DEVICE_CODE_TTL_MINUTES = 15;
4346
+ var DEFAULT_DEVICE_CODE_TTL_MS = MILLISECONDS_IN_A_MINUTE * DEFAULT_DEVICE_CODE_TTL_MINUTES;
4347
+ var DEFAULT_DEVICE_POLL_INTERVAL_SECONDS = 5;
4348
+ var generateUserCode = () => {
4349
+ const length = USER_CODE_HALF_LENGTH * 2;
4350
+ const random = crypto.getRandomValues(new Uint8Array(length));
4351
+ let code = "";
4352
+ for (const byte of random) {
4353
+ code += USER_CODE_ALPHABET[byte % USER_CODE_ALPHABET.length];
4354
+ }
4355
+ return `${code.slice(0, USER_CODE_HALF_LENGTH)}-${code.slice(USER_CODE_HALF_LENGTH)}`;
4356
+ };
4357
+ var issueDeviceAuthorization = async ({
4358
+ clientId,
4359
+ config,
4360
+ now = Date.now(),
4361
+ requestedScopes
4362
+ }) => {
4363
+ if (!config.deviceAuthorizationStore) {
4364
+ throw new Error("oidc.deviceAuthorizationStore is not configured \u2014 cannot start a device flow");
4365
+ }
4366
+ const deviceCode = generateSecureToken(DEVICE_CODE_BYTES);
4367
+ const userCode = generateUserCode();
4368
+ const ttl = config.deviceCodeTtlMs ?? DEFAULT_DEVICE_CODE_TTL_MS;
4369
+ const interval = config.devicePollIntervalSeconds ?? DEFAULT_DEVICE_POLL_INTERVAL_SECONDS;
4370
+ await config.deviceAuthorizationStore.saveDeviceAuthorization({
4371
+ clientId,
4372
+ createdAt: now,
4373
+ deviceCodeHash: await hashToken(deviceCode),
4374
+ expiresAt: now + ttl,
4375
+ intervalSeconds: interval,
4376
+ scopes: requestedScopes,
4377
+ status: "pending",
4378
+ userCode
4379
+ });
4380
+ const verificationUri = `${config.issuer}${config.oidcRoute ?? DEFAULT_OIDC_ROUTE}/device`;
4381
+ return {
4382
+ device_code: deviceCode,
4383
+ expires_in: Math.floor(ttl / MS_PER_SECOND),
4384
+ interval,
4385
+ user_code: userCode,
4386
+ verification_uri: verificationUri,
4387
+ verification_uri_complete: `${verificationUri}?user_code=${encodeURIComponent(userCode)}`
4388
+ };
4389
+ };
4390
+ var decideDeviceAuthorization = async (config, userCode, approval) => {
4391
+ if (!config.deviceAuthorizationStore) {
4392
+ return { error: "not_configured", ok: false };
4393
+ }
4394
+ const record = await config.deviceAuthorizationStore.findByUserCode(userCode);
4395
+ if (!record)
4396
+ return { error: "invalid_user_code", ok: false };
4397
+ if (record.expiresAt < Date.now()) {
4398
+ return { error: "expired_token", ok: false };
4399
+ }
4400
+ if (record.status !== "pending") {
4401
+ return { error: "already_decided", ok: false };
4402
+ }
4403
+ await config.deviceAuthorizationStore.updateStatus(record.deviceCodeHash, approval.status, approval.userSub);
4404
+ return { ok: true };
4405
+ };
4406
+ var approveDeviceAuthorization = async ({
4407
+ config,
4408
+ userCode,
4409
+ userSub
4410
+ }) => decideDeviceAuthorization(config, userCode, {
4411
+ status: "approved",
4412
+ userSub
4413
+ });
4414
+ var denyDeviceAuthorization = async ({
4415
+ config,
4416
+ userCode
4417
+ }) => decideDeviceAuthorization(config, userCode, { status: "denied" });
4418
+ var exchangeDeviceCode = async ({
4419
+ clientId,
4420
+ config,
4421
+ deviceCode,
4422
+ dpopJkt,
4423
+ now = Date.now()
4424
+ }) => {
4425
+ if (!config.deviceAuthorizationStore) {
4426
+ return { error: "invalid_grant", ok: false };
4427
+ }
4428
+ const deviceCodeHash = await hashToken(deviceCode);
4429
+ const record = await config.deviceAuthorizationStore.findByDeviceCodeHash(deviceCodeHash);
4430
+ if (!record || record.clientId !== clientId) {
4431
+ return { error: "invalid_grant", ok: false };
4432
+ }
4433
+ if (record.expiresAt < now) {
4434
+ await config.deviceAuthorizationStore.deleteByDeviceCodeHash(deviceCodeHash);
4435
+ return { error: "expired_token", ok: false };
4436
+ }
4437
+ if (record.status === "pending") {
4438
+ return { error: "authorization_pending", ok: false };
4439
+ }
4440
+ if (record.status === "denied" || record.userSub === undefined) {
4441
+ return { error: "access_denied", ok: false };
4442
+ }
4443
+ await config.deviceAuthorizationStore.deleteByDeviceCodeHash(deviceCodeHash);
4444
+ const tokenSet = await issueTokenSet({
4445
+ clientId,
4446
+ config,
4447
+ dpopJkt,
4448
+ now,
4449
+ scopes: record.scopes,
4450
+ sub: record.userSub
4451
+ });
4452
+ return { ...tokenSet, ok: true };
4453
+ };
4300
4454
 
4301
4455
  // src/oidc/dpop.ts
4302
4456
  var DEFAULT_MAX_AGE_MS = 60000;
@@ -4391,6 +4545,10 @@ var oidcProviderRoutes = (config) => {
4391
4545
  const authorizeRoute = `${oidcRoute}/authorize`;
4392
4546
  const tokenRoute = `${oidcRoute}/token`;
4393
4547
  const jwksRoute = `${oidcRoute}/jwks`;
4548
+ const introspectRoute = `${oidcRoute}/introspect`;
4549
+ const revokeRoute = `${oidcRoute}/revoke`;
4550
+ const deviceAuthorizationRoute = `${oidcRoute}/device_authorization`;
4551
+ const deviceApproveRoute = `${oidcRoute}/device/decision`;
4394
4552
  const tokenUrl = `${issuer}${oidcRoute}/token`;
4395
4553
  const authenticateClient = async (clientId, clientSecret) => {
4396
4554
  const client = await clientStore.findClient(clientId);
@@ -4492,19 +4650,57 @@ var oidcProviderRoutes = (config) => {
4492
4650
  token_type: dpopResult === undefined ? "Bearer" : "DPoP"
4493
4651
  }, HTTP_OK2);
4494
4652
  };
4653
+ const grantDeviceCode = async (client, body, dpop) => {
4654
+ if (config.deviceAuthorizationStore === undefined) {
4655
+ return oauthError2(HTTP_BAD_REQUEST2, "unsupported_grant_type");
4656
+ }
4657
+ if (body.device_code === undefined) {
4658
+ return oauthError2(HTTP_BAD_REQUEST2, "invalid_request");
4659
+ }
4660
+ const dpopResult = dpop === undefined ? undefined : await verifyDpopProof({
4661
+ htm: "POST",
4662
+ htu: tokenUrl,
4663
+ proof: dpop
4664
+ });
4665
+ if (dpop !== undefined && dpopResult === undefined) {
4666
+ return oauthError2(HTTP_BAD_REQUEST2, "invalid_dpop_proof");
4667
+ }
4668
+ const result = await exchangeDeviceCode({
4669
+ clientId: client.clientId,
4670
+ config,
4671
+ deviceCode: body.device_code,
4672
+ dpopJkt: dpopResult?.jkt
4673
+ });
4674
+ if (!result.ok)
4675
+ return oauthError2(HTTP_BAD_REQUEST2, result.error);
4676
+ return jsonResponse({
4677
+ access_token: result.access_token,
4678
+ expires_in: result.expires_in,
4679
+ id_token: result.id_token,
4680
+ refresh_token: result.refresh_token,
4681
+ scope: result.scope,
4682
+ token_type: dpopResult === undefined ? "Bearer" : "DPoP"
4683
+ }, HTTP_OK2);
4684
+ };
4685
+ const grantTypes = [
4686
+ "authorization_code",
4687
+ "refresh_token",
4688
+ "urn:ietf:params:oauth:grant-type:token-exchange"
4689
+ ];
4690
+ if (config.deviceAuthorizationStore) {
4691
+ grantTypes.push("urn:ietf:params:oauth:grant-type:device_code");
4692
+ }
4495
4693
  const discovery = {
4496
4694
  authorization_endpoint: `${issuer}${authorizeRoute}`,
4497
4695
  code_challenge_methods_supported: ["S256"],
4498
4696
  dpop_signing_alg_values_supported: ["ES256"],
4499
- grant_types_supported: [
4500
- "authorization_code",
4501
- "refresh_token",
4502
- "urn:ietf:params:oauth:grant-type:token-exchange"
4503
- ],
4697
+ grant_types_supported: grantTypes,
4504
4698
  id_token_signing_alg_values_supported: ["ES256"],
4699
+ introspection_endpoint: `${issuer}${introspectRoute}`,
4505
4700
  issuer,
4506
4701
  jwks_uri: `${issuer}${jwksRoute}`,
4507
4702
  response_types_supported: ["code"],
4703
+ revocation_endpoint: `${issuer}${revokeRoute}`,
4508
4704
  subject_types_supported: ["public"],
4509
4705
  token_endpoint: tokenUrl,
4510
4706
  token_endpoint_auth_methods_supported: [
@@ -4513,6 +4709,9 @@ var oidcProviderRoutes = (config) => {
4513
4709
  "none"
4514
4710
  ]
4515
4711
  };
4712
+ if (config.deviceAuthorizationStore) {
4713
+ discovery.device_authorization_endpoint = `${issuer}${deviceAuthorizationRoute}`;
4714
+ }
4516
4715
  return new Elysia15().use(sessionStore()).get(authorizeRoute, async ({ cookie: { user_session_id }, query, request, store }) => {
4517
4716
  const {
4518
4717
  client_id: clientId,
@@ -4610,6 +4809,9 @@ var oidcProviderRoutes = (config) => {
4610
4809
  if (body.grant_type === "urn:ietf:params:oauth:grant-type:token-exchange") {
4611
4810
  return grantTokenExchange(client, body, headers.dpop);
4612
4811
  }
4812
+ if (body.grant_type === "urn:ietf:params:oauth:grant-type:device_code") {
4813
+ return grantDeviceCode(client, body, headers.dpop);
4814
+ }
4613
4815
  return oauthError2(HTTP_BAD_REQUEST2, "unsupported_grant_type");
4614
4816
  }, {
4615
4817
  body: t12.Object({
@@ -4618,6 +4820,7 @@ var oidcProviderRoutes = (config) => {
4618
4820
  client_secret: t12.Optional(t12.String()),
4619
4821
  code: t12.Optional(t12.String()),
4620
4822
  code_verifier: t12.Optional(t12.String()),
4823
+ device_code: t12.Optional(t12.String()),
4621
4824
  grant_type: t12.Optional(t12.String()),
4622
4825
  redirect_uri: t12.Optional(t12.String()),
4623
4826
  refresh_token: t12.Optional(t12.String()),
@@ -4626,6 +4829,121 @@ var oidcProviderRoutes = (config) => {
4626
4829
  subject_token: t12.Optional(t12.String()),
4627
4830
  subject_token_type: t12.Optional(t12.String())
4628
4831
  })
4832
+ }).post(introspectRoute, async ({ body, headers }) => {
4833
+ const basic = readBasicAuth2(headers.authorization);
4834
+ const clientId = body.client_id ?? basic.clientId;
4835
+ const clientSecret = body.client_secret ?? basic.clientSecret;
4836
+ if (clientId === undefined) {
4837
+ return oauthError2(HTTP_UNAUTHORIZED2, "invalid_client");
4838
+ }
4839
+ const client = await authenticateClient(clientId, clientSecret);
4840
+ if (client === undefined) {
4841
+ return oauthError2(HTTP_UNAUTHORIZED2, "invalid_client");
4842
+ }
4843
+ const result = await introspectToken({
4844
+ config,
4845
+ hint: body.token_type_hint === "access_token" || body.token_type_hint === "refresh_token" ? body.token_type_hint : undefined,
4846
+ now: Date.now(),
4847
+ token: body.token
4848
+ });
4849
+ return jsonResponse(result, HTTP_OK2);
4850
+ }, {
4851
+ body: t12.Object({
4852
+ client_id: t12.Optional(t12.String()),
4853
+ client_secret: t12.Optional(t12.String()),
4854
+ token: t12.String(),
4855
+ token_type_hint: t12.Optional(t12.String())
4856
+ }),
4857
+ headers: t12.Object({
4858
+ authorization: t12.Optional(t12.String())
4859
+ })
4860
+ }).post(revokeRoute, async ({ body, headers }) => {
4861
+ const basic = readBasicAuth2(headers.authorization);
4862
+ const clientId = body.client_id ?? basic.clientId;
4863
+ const clientSecret = body.client_secret ?? basic.clientSecret;
4864
+ if (clientId === undefined) {
4865
+ return oauthError2(HTTP_UNAUTHORIZED2, "invalid_client");
4866
+ }
4867
+ const client = await authenticateClient(clientId, clientSecret);
4868
+ if (client === undefined) {
4869
+ return oauthError2(HTTP_UNAUTHORIZED2, "invalid_client");
4870
+ }
4871
+ if (body.token_type_hint !== "access_token") {
4872
+ await revokeRefreshToken(config, body.token);
4873
+ }
4874
+ return new Response(null, { status: HTTP_OK2 });
4875
+ }, {
4876
+ body: t12.Object({
4877
+ client_id: t12.Optional(t12.String()),
4878
+ client_secret: t12.Optional(t12.String()),
4879
+ token: t12.String(),
4880
+ token_type_hint: t12.Optional(t12.String())
4881
+ }),
4882
+ headers: t12.Object({
4883
+ authorization: t12.Optional(t12.String())
4884
+ })
4885
+ }).post(deviceAuthorizationRoute, async ({ body, headers }) => {
4886
+ if (config.deviceAuthorizationStore === undefined) {
4887
+ return oauthError2(HTTP_BAD_REQUEST2, "unsupported_grant_type");
4888
+ }
4889
+ const basic = readBasicAuth2(headers.authorization);
4890
+ const clientId = body.client_id ?? basic.clientId;
4891
+ const clientSecret = body.client_secret ?? basic.clientSecret;
4892
+ if (clientId === undefined) {
4893
+ return oauthError2(HTTP_UNAUTHORIZED2, "invalid_client");
4894
+ }
4895
+ const client = await authenticateClient(clientId, clientSecret);
4896
+ if (client === undefined) {
4897
+ return oauthError2(HTTP_UNAUTHORIZED2, "invalid_client");
4898
+ }
4899
+ const requested = body.scope === undefined || body.scope.length === 0 ? client.scopes : body.scope.split(" ").filter((entry) => client.scopes.includes(entry));
4900
+ const response = await issueDeviceAuthorization({
4901
+ clientId: client.clientId,
4902
+ config,
4903
+ now: Date.now(),
4904
+ requestedScopes: requested
4905
+ });
4906
+ return jsonResponse(response, HTTP_OK2);
4907
+ }, {
4908
+ body: t12.Object({
4909
+ client_id: t12.Optional(t12.String()),
4910
+ client_secret: t12.Optional(t12.String()),
4911
+ scope: t12.Optional(t12.String())
4912
+ }),
4913
+ headers: t12.Object({
4914
+ authorization: t12.Optional(t12.String())
4915
+ })
4916
+ }).post(deviceApproveRoute, async ({ body, cookie: { user_session_id }, store }) => {
4917
+ if (config.deviceAuthorizationStore === undefined) {
4918
+ return oauthError2(HTTP_BAD_REQUEST2, "unsupported_grant_type");
4919
+ }
4920
+ const userSession = await loadSessionFromSource({
4921
+ authSessionStore,
4922
+ session: store.session,
4923
+ userSessionId: user_session_id.value
4924
+ });
4925
+ if (userSession === undefined) {
4926
+ return oauthError2(HTTP_UNAUTHORIZED2, "login_required");
4927
+ }
4928
+ const result = body.action === "deny" ? await denyDeviceAuthorization({
4929
+ config,
4930
+ userCode: body.user_code
4931
+ }) : await approveDeviceAuthorization({
4932
+ config,
4933
+ userCode: body.user_code,
4934
+ userSub: getUserId(userSession.user)
4935
+ });
4936
+ if (!result.ok)
4937
+ return oauthError2(HTTP_BAD_REQUEST2, result.error);
4938
+ return jsonResponse({ ok: true }, HTTP_OK2);
4939
+ }, {
4940
+ body: t12.Object({
4941
+ action: t12.Optional(t12.Union([t12.Literal("approve"), t12.Literal("deny")])),
4942
+ user_code: t12.String()
4943
+ }),
4944
+ cookie: t12.Cookie({
4945
+ user_session_id: t12.Optional(userSessionIdTypebox)
4946
+ })
4629
4947
  }).get(jwksRoute, () => ({ keys: [toPublicJwk(signingKey)] })).get("/.well-known/openid-configuration", () => discovery);
4630
4948
  };
4631
4949
 
@@ -19646,6 +19964,33 @@ var createInMemoryAuthorizationCodeStore = () => {
19646
19964
  }
19647
19965
  };
19648
19966
  };
19967
+ var createInMemoryDeviceAuthorizationStore = () => {
19968
+ const byDeviceCode = new Map;
19969
+ return {
19970
+ deleteByDeviceCodeHash: async (deviceCodeHash) => {
19971
+ byDeviceCode.delete(deviceCodeHash);
19972
+ },
19973
+ findByDeviceCodeHash: async (deviceCodeHash) => byDeviceCode.get(deviceCodeHash),
19974
+ findByUserCode: async (userCode) => {
19975
+ for (const record of byDeviceCode.values()) {
19976
+ if (record.userCode === userCode)
19977
+ return record;
19978
+ }
19979
+ return;
19980
+ },
19981
+ saveDeviceAuthorization: async (deviceAuthorization) => {
19982
+ byDeviceCode.set(deviceAuthorization.deviceCodeHash, {
19983
+ ...deviceAuthorization
19984
+ });
19985
+ },
19986
+ updateStatus: async (deviceCodeHash, status, userSub) => {
19987
+ const record = byDeviceCode.get(deviceCodeHash);
19988
+ if (!record)
19989
+ return;
19990
+ byDeviceCode.set(deviceCodeHash, { ...record, status, userSub });
19991
+ }
19992
+ };
19993
+ };
19649
19994
  var createInMemoryOAuthClientStore = (clients) => {
19650
19995
  const registry = new Map(clients.map((client) => [client.clientId, client]));
19651
19996
  return {
@@ -19666,6 +20011,7 @@ var createInMemoryOidcRefreshTokenStore = () => {
19666
20011
  tokens.delete(hash);
19667
20012
  }
19668
20013
  },
20014
+ getToken: async (tokenHash) => tokens.get(tokenHash),
19669
20015
  saveToken: async (token) => {
19670
20016
  tokens.set(token.tokenHash, { ...token });
19671
20017
  }
@@ -19693,6 +20039,19 @@ var oauthCodesTable = pgTable("auth_oauth_codes", {
19693
20039
  scopes: text("scopes").array().notNull(),
19694
20040
  user_id: varchar("user_id", { length: ID_LENGTH7 }).notNull()
19695
20041
  });
20042
+ var oauthDeviceAuthorizationsTable = pgTable("auth_oauth_device_authorizations", {
20043
+ client_id: varchar("client_id", { length: ID_LENGTH7 }).notNull(),
20044
+ created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
20045
+ device_code_hash: varchar("device_code_hash", {
20046
+ length: ID_LENGTH7
20047
+ }).primaryKey(),
20048
+ expires_at_ms: bigint("expires_at_ms", { mode: "number" }).notNull(),
20049
+ interval_seconds: bigint("interval_seconds", { mode: "number" }).notNull(),
20050
+ scopes: text("scopes").array().notNull(),
20051
+ status: varchar("status", { length: 16 }).notNull(),
20052
+ user_code: varchar("user_code", { length: 16 }).notNull().unique(),
20053
+ user_sub: varchar("user_sub", { length: ID_LENGTH7 })
20054
+ });
19696
20055
  var oauthRefreshTokensTable = pgTable("auth_oauth_refresh_tokens", {
19697
20056
  claims_json: jsonb("claims_json").$type(),
19698
20057
  client_id: varchar("client_id", { length: ID_LENGTH7 }).notNull(),
@@ -19736,6 +20095,17 @@ var toCodeValues = (code) => ({
19736
20095
  scopes: code.scopes,
19737
20096
  user_id: code.userId
19738
20097
  });
20098
+ var toDeviceAuth = (row) => ({
20099
+ clientId: row.client_id,
20100
+ createdAt: row.created_at_ms,
20101
+ deviceCodeHash: row.device_code_hash,
20102
+ expiresAt: row.expires_at_ms,
20103
+ intervalSeconds: row.interval_seconds,
20104
+ scopes: row.scopes,
20105
+ status: row.status,
20106
+ userCode: row.user_code,
20107
+ userSub: row.user_sub ?? undefined
20108
+ });
19739
20109
  var toRefresh = (row) => ({
19740
20110
  claims: row.claims_json ?? undefined,
19741
20111
  clientId: row.client_id,
@@ -19757,6 +20127,7 @@ var toRefreshValues = (token) => ({
19757
20127
  user_id: token.userId
19758
20128
  });
19759
20129
  var createNeonAuthorizationCodeStore = (databaseUrl) => createPostgresAuthorizationCodeStore(createNeonDatabase(databaseUrl));
20130
+ var createNeonDeviceAuthorizationStore = (databaseUrl) => createPostgresDeviceAuthorizationStore(createNeonDatabase(databaseUrl));
19760
20131
  var createNeonOAuthClientStore = (databaseUrl) => createPostgresOAuthClientStore(createNeonDatabase(databaseUrl));
19761
20132
  var createNeonOidcRefreshTokenStore = (databaseUrl) => createPostgresOidcRefreshTokenStore(createNeonDatabase(databaseUrl));
19762
20133
  var createPostgresAuthorizationCodeStore = (db) => ({
@@ -19768,6 +20139,35 @@ var createPostgresAuthorizationCodeStore = (db) => ({
19768
20139
  await db.insert(oauthCodesTable).values(toCodeValues(code));
19769
20140
  }
19770
20141
  });
20142
+ var createPostgresDeviceAuthorizationStore = (db) => ({
20143
+ deleteByDeviceCodeHash: async (deviceCodeHash) => {
20144
+ await db.delete(oauthDeviceAuthorizationsTable).where(eq(oauthDeviceAuthorizationsTable.device_code_hash, deviceCodeHash));
20145
+ },
20146
+ findByDeviceCodeHash: async (deviceCodeHash) => {
20147
+ const [row] = await db.select().from(oauthDeviceAuthorizationsTable).where(eq(oauthDeviceAuthorizationsTable.device_code_hash, deviceCodeHash)).limit(1);
20148
+ return row ? toDeviceAuth(row) : undefined;
20149
+ },
20150
+ findByUserCode: async (userCode) => {
20151
+ const [row] = await db.select().from(oauthDeviceAuthorizationsTable).where(eq(oauthDeviceAuthorizationsTable.user_code, userCode)).limit(1);
20152
+ return row ? toDeviceAuth(row) : undefined;
20153
+ },
20154
+ saveDeviceAuthorization: async (deviceAuthorization) => {
20155
+ await db.insert(oauthDeviceAuthorizationsTable).values({
20156
+ client_id: deviceAuthorization.clientId,
20157
+ created_at_ms: deviceAuthorization.createdAt,
20158
+ device_code_hash: deviceAuthorization.deviceCodeHash,
20159
+ expires_at_ms: deviceAuthorization.expiresAt,
20160
+ interval_seconds: deviceAuthorization.intervalSeconds,
20161
+ scopes: deviceAuthorization.scopes,
20162
+ status: deviceAuthorization.status,
20163
+ user_code: deviceAuthorization.userCode,
20164
+ user_sub: deviceAuthorization.userSub ?? null
20165
+ });
20166
+ },
20167
+ updateStatus: async (deviceCodeHash, status, userSub) => {
20168
+ await db.update(oauthDeviceAuthorizationsTable).set({ status, user_sub: userSub ?? null }).where(eq(oauthDeviceAuthorizationsTable.device_code_hash, deviceCodeHash));
20169
+ }
20170
+ });
19771
20171
  var createPostgresOAuthClientStore = (db) => ({
19772
20172
  findClient: async (clientId) => {
19773
20173
  const [row] = await db.select().from(oauthClientsTable).where(eq(oauthClientsTable.client_id, clientId)).limit(1);
@@ -19782,6 +20182,10 @@ var createPostgresOidcRefreshTokenStore = (db) => ({
19782
20182
  deleteForUser: async (userId) => {
19783
20183
  await db.delete(oauthRefreshTokensTable).where(eq(oauthRefreshTokensTable.user_id, userId));
19784
20184
  },
20185
+ getToken: async (tokenHash) => {
20186
+ const [row] = await db.select().from(oauthRefreshTokensTable).where(eq(oauthRefreshTokensTable.token_hash, tokenHash)).limit(1);
20187
+ return row ? toRefresh(row) : undefined;
20188
+ },
19785
20189
  saveToken: async (token) => {
19786
20190
  await db.insert(oauthRefreshTokensTable).values(toRefreshValues(token));
19787
20191
  }
@@ -21182,6 +21586,7 @@ export {
21182
21586
  rolesTable,
21183
21587
  roleRoutes,
21184
21588
  revokeUserSessions,
21589
+ revokeRefreshToken,
21185
21590
  revocableProviderOptions,
21186
21591
  resolveSetupSession,
21187
21592
  resolveScimOrganization,
@@ -21213,6 +21618,7 @@ export {
21213
21618
  oidcProviderRoutes,
21214
21619
  oidcProviderOptions,
21215
21620
  oauthRefreshTokensTable,
21621
+ oauthDeviceAuthorizationsTable,
21216
21622
  oauthCodesTable,
21217
21623
  oauthClientsTable,
21218
21624
  mfaTotpRoutes,
@@ -21230,6 +21636,7 @@ export {
21230
21636
  knownDevicesTable,
21231
21637
  jwkThumbprint,
21232
21638
  issueTokenSet,
21639
+ issueDeviceAuthorization,
21233
21640
  isValidUser,
21234
21641
  isValidProviderOption,
21235
21642
  isUserSessionId,
@@ -21246,6 +21653,7 @@ export {
21246
21653
  isAuthIntent,
21247
21654
  isAnonymousSession,
21248
21655
  inviteToOrganization,
21656
+ introspectToken,
21249
21657
  instantiateUserSession,
21250
21658
  hashToken,
21251
21659
  hashPassword,
@@ -21264,11 +21672,13 @@ export {
21264
21672
  extractPropFromIdentity,
21265
21673
  exportAuditCsv,
21266
21674
  exchangeToken,
21675
+ exchangeDeviceCode,
21267
21676
  exchangeClientCredentials,
21268
21677
  evaluatePassword,
21269
21678
  endImpersonation,
21270
21679
  encryptTotpSecret,
21271
21680
  encryptSecret,
21681
+ denyDeviceAuthorization,
21272
21682
  deleteWarrant,
21273
21683
  defineProvidersConfiguration,
21274
21684
  defineAuthSettings,
@@ -21312,6 +21722,7 @@ export {
21312
21722
  createPostgresLoginHistoryStore,
21313
21723
  createPostgresLockoutStore,
21314
21724
  createPostgresKnownDeviceStore,
21725
+ createPostgresDeviceAuthorizationStore,
21315
21726
  createPostgresCredentialStore,
21316
21727
  createPostgresAuthorizationCodeStore,
21317
21728
  createPostgresAuditSink,
@@ -21337,6 +21748,7 @@ export {
21337
21748
  createNeonLockoutStore,
21338
21749
  createNeonLinkedProviderStores,
21339
21750
  createNeonKnownDeviceStore,
21751
+ createNeonDeviceAuthorizationStore,
21340
21752
  createNeonDatabase,
21341
21753
  createNeonCredentialStore,
21342
21754
  createNeonAuthorizationCodeStore,
@@ -21365,6 +21777,7 @@ export {
21365
21777
  createInMemoryLockoutStore,
21366
21778
  createInMemoryLinkedProviderStores,
21367
21779
  createInMemoryKnownDeviceStore,
21780
+ createInMemoryDeviceAuthorizationStore,
21368
21781
  createInMemoryCredentialStore,
21369
21782
  createInMemoryCheckCache,
21370
21783
  createInMemoryAuthorizationCodeStore,
@@ -21396,6 +21809,7 @@ export {
21396
21809
  auditEventsTable,
21397
21810
  assessRisk,
21398
21811
  assessAbuse,
21812
+ approveDeviceAuthorization,
21399
21813
  apiKeysTable,
21400
21814
  apiKeysRoutes,
21401
21815
  apiClientsTable,
@@ -21432,5 +21846,5 @@ export {
21432
21846
  AuthIdentityConflictError
21433
21847
  };
21434
21848
 
21435
- //# debugId=CE0246297ACE345E64756E2164756E21
21849
+ //# debugId=E246ECC6A14E235864756E2164756E21
21436
21850
  //# sourceMappingURL=index.js.map