@absolutejs/auth 0.34.0 → 0.35.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
@@ -1,4 +1,6 @@
1
1
  // @bun
2
+ var __require = import.meta.require;
3
+
2
4
  // node_modules/citra/dist/index.js
3
5
  var BASE64_BLOCK_SIZE = 4;
4
6
  var NUM_GENERATOR_BYTES = 32;
@@ -3675,6 +3677,32 @@ var verifyCognitoSha256 = async (plainPassword, wrappedHash) => {
3675
3677
  return constantTimeEqualBytes(derived, expected);
3676
3678
  };
3677
3679
 
3680
+ // src/telemetry/tracing.ts
3681
+ var DEFAULT_SERVICE_NAME = "@absolutejs/auth";
3682
+ var noopWithSpan = (_name, _attributes, work) => work(undefined);
3683
+ var activeWithSpan = noopWithSpan;
3684
+ var initTracing = async (config) => {
3685
+ const otel = await import("@opentelemetry/api");
3686
+ const tracer = config.tracerProvider.getTracer(config.serviceName ?? DEFAULT_SERVICE_NAME);
3687
+ activeWithSpan = async (name, attributes, work) => {
3688
+ const span = tracer.startSpan(name, { attributes });
3689
+ try {
3690
+ const result = await otel.context.with(otel.trace.setSpan(otel.context.active(), span), () => work(span));
3691
+ span.setStatus({ code: otel.SpanStatusCode.OK });
3692
+ return result;
3693
+ } catch (error) {
3694
+ const message = error instanceof Error ? error.message : "unknown";
3695
+ if (error instanceof Error)
3696
+ span.recordException(error);
3697
+ span.setStatus({ code: otel.SpanStatusCode.ERROR, message });
3698
+ throw error;
3699
+ } finally {
3700
+ span.end();
3701
+ }
3702
+ };
3703
+ };
3704
+ var withSpan = (name, attributes, work) => activeWithSpan(name, attributes, work);
3705
+
3678
3706
  // src/credentials/passwordPolicy.ts
3679
3707
  var DEFAULT_MIN_LENGTH = 12;
3680
3708
  var HEX_RADIX = 16;
@@ -3746,7 +3774,7 @@ var credentialsLogin = ({
3746
3774
  request,
3747
3775
  status,
3748
3776
  store: { session, unregisteredSession }
3749
- }) => {
3777
+ }) => withSpan("auth.credentials.login", undefined, async (span) => {
3750
3778
  const headerBag = {};
3751
3779
  request.headers.forEach((value, key) => {
3752
3780
  headerBag[key] = value;
@@ -3817,7 +3845,7 @@ var credentialsLogin = ({
3817
3845
  });
3818
3846
  await onCredentialsLoginSuccess?.({ user, userSessionId });
3819
3847
  return status("OK", { passwordCompromised, status: "authenticated" });
3820
- }, {
3848
+ }), {
3821
3849
  body: t6.Object({ email: t6.String(), password: t6.String() }),
3822
3850
  cookie: t6.Cookie({ user_session_id: userSessionIdTypebox })
3823
3851
  });
@@ -3900,7 +3928,7 @@ var credentialsRegister = ({
3900
3928
  cookie: { user_session_id },
3901
3929
  status,
3902
3930
  store: { session }
3903
- }) => {
3931
+ }) => withSpan("auth.credentials.register", undefined, async () => {
3904
3932
  const normalizedEmail = email.trim().toLowerCase();
3905
3933
  if (!normalizedEmail.includes("@")) {
3906
3934
  return status("Bad Request", "A valid email is required");
@@ -3962,7 +3990,7 @@ var credentialsRegister = ({
3962
3990
  });
3963
3991
  await onCredentialsLoginSuccess?.({ user: created, userSessionId });
3964
3992
  return status("Created", { status: "authenticated" });
3965
- }, {
3993
+ }), {
3966
3994
  body: t8.Object({ email: t8.String(), password: t8.String() }, { additionalProperties: true }),
3967
3995
  cookie: t8.Cookie({ user_session_id: userSessionIdTypebox })
3968
3996
  });
@@ -4237,7 +4265,7 @@ var mfaChallenge = ({
4237
4265
  cookie: { user_session_id },
4238
4266
  status,
4239
4267
  store: { session, unregisteredSession }
4240
- }) => {
4268
+ }) => withSpan("auth.mfa.challenge", undefined, async () => {
4241
4269
  const compatibilityLayer = await createSessionCompatibilityLayer({
4242
4270
  authSessionStore,
4243
4271
  userSessionId: user_session_id.value
@@ -4288,7 +4316,7 @@ var mfaChallenge = ({
4288
4316
  await persistWhen(authSessionStore !== undefined, compatibilityLayer.persist);
4289
4317
  await onMfaChallengeSuccess?.({ user, userSessionId });
4290
4318
  return status("OK", { status: "authenticated" });
4291
- }, {
4319
+ }), {
4292
4320
  body: t10.Object({ code: t10.String() }),
4293
4321
  cookie: t10.Cookie({ user_session_id: userSessionIdTypebox })
4294
4322
  });
@@ -7428,7 +7456,7 @@ var callback = ({
7428
7456
  auth_intent
7429
7457
  },
7430
7458
  query: { code, state: callback_state }
7431
- }) => {
7459
+ }) => withSpan("auth.oauth.callback", { "auth.provider": auth_provider?.value }, async () => {
7432
7460
  if (stored_state === undefined || code_verifier === undefined || user_session_id === undefined || auth_client === undefined || auth_intent === undefined) {
7433
7461
  return status("Bad Request", "Cookies are missing");
7434
7462
  }
@@ -7539,7 +7567,7 @@ var callback = ({
7539
7567
  return response;
7540
7568
  }
7541
7569
  return redirect(originUrl);
7542
- }, {
7570
+ }), {
7543
7571
  cookie: t18.Cookie({
7544
7572
  auth_client: authClientOption,
7545
7573
  auth_intent: authIntentOption,
@@ -7890,7 +7918,7 @@ var signout = ({
7890
7918
  status,
7891
7919
  store: { session },
7892
7920
  cookie: { user_session_id, auth_provider }
7893
- }) => {
7921
+ }) => withSpan("auth.signout", { "auth.provider": auth_provider?.value }, async () => {
7894
7922
  if (user_session_id === undefined) {
7895
7923
  return status("Bad Request", "Cookies are missing");
7896
7924
  }
@@ -7924,7 +7952,7 @@ var signout = ({
7924
7952
  user_session_id.remove();
7925
7953
  auth_provider?.remove();
7926
7954
  return new Response(null, { status: 204 });
7927
- }, {
7955
+ }), {
7928
7956
  cookie: t24.Cookie({
7929
7957
  auth_provider: t24.Optional(authProviderOption),
7930
7958
  user_session_id: t24.Optional(t24.TemplateLiteral("${string}-${string}-${string}-${string}-${string}"))
@@ -9316,16 +9344,24 @@ var attemptOnce = async ({
9316
9344
  timeoutMs,
9317
9345
  timestamp
9318
9346
  }) => {
9319
- const response = await fetchImpl(endpoint.url, {
9320
- body: payload,
9321
- headers: {
9322
- "content-type": "application/json",
9323
- "webhook-id": envelope.id,
9324
- "webhook-signature": signature,
9325
- "webhook-timestamp": timestamp
9326
- },
9327
- method: "POST",
9328
- signal: AbortSignal.timeout(timeoutMs)
9347
+ const response = await withSpan("auth.webhook.deliver", {
9348
+ "auth.webhook.event": envelope.type,
9349
+ "auth.webhook.url": endpoint.url,
9350
+ "http.method": "POST"
9351
+ }, async (span) => {
9352
+ const result = await fetchImpl(endpoint.url, {
9353
+ body: payload,
9354
+ headers: {
9355
+ "content-type": "application/json",
9356
+ "webhook-id": envelope.id,
9357
+ "webhook-signature": signature,
9358
+ "webhook-timestamp": timestamp
9359
+ },
9360
+ method: "POST",
9361
+ signal: AbortSignal.timeout(timeoutMs)
9362
+ });
9363
+ span?.setAttribute("http.status_code", result.status);
9364
+ return result;
9329
9365
  });
9330
9366
  if (!response.ok) {
9331
9367
  throw new Error(`Webhook delivery returned ${response.status}`);
@@ -9756,6 +9792,38 @@ function uniqueKeyName(table, columns) {
9756
9792
  return `${table[TableName]}_${columns.join("_")}_unique`;
9757
9793
  }
9758
9794
 
9795
+ class UniqueConstraintBuilder {
9796
+ constructor(columns, name) {
9797
+ this.name = name;
9798
+ this.columns = columns;
9799
+ }
9800
+ static [entityKind] = "PgUniqueConstraintBuilder";
9801
+ columns;
9802
+ nullsNotDistinctConfig = false;
9803
+ nullsNotDistinct() {
9804
+ this.nullsNotDistinctConfig = true;
9805
+ return this;
9806
+ }
9807
+ build(table) {
9808
+ return new UniqueConstraint(table, this.columns, this.nullsNotDistinctConfig, this.name);
9809
+ }
9810
+ }
9811
+ class UniqueConstraint {
9812
+ constructor(table, columns, nullsNotDistinct, name) {
9813
+ this.table = table;
9814
+ this.columns = columns;
9815
+ this.name = name ?? uniqueKeyName(this.table, this.columns.map((column) => column.name));
9816
+ this.nullsNotDistinct = nullsNotDistinct;
9817
+ }
9818
+ static [entityKind] = "PgUniqueConstraint";
9819
+ columns;
9820
+ name;
9821
+ nullsNotDistinct = false;
9822
+ getName() {
9823
+ return this.name;
9824
+ }
9825
+ }
9826
+
9759
9827
  // node_modules/drizzle-orm/pg-core/utils/array.js
9760
9828
  function parsePgArrayValue(arrayString, startFrom, inQuotes) {
9761
9829
  for (let i = startFrom;i < arrayString.length; i++) {
@@ -12440,6 +12508,30 @@ function mapRelationalRow(tablesConfig, tableConfig, row, buildQueryResultSelect
12440
12508
  return result;
12441
12509
  }
12442
12510
 
12511
+ // node_modules/drizzle-orm/pg-core/checks.js
12512
+ class CheckBuilder {
12513
+ constructor(name, value) {
12514
+ this.name = name;
12515
+ this.value = value;
12516
+ }
12517
+ static [entityKind] = "PgCheckBuilder";
12518
+ brand;
12519
+ build(table) {
12520
+ return new Check(table, this);
12521
+ }
12522
+ }
12523
+
12524
+ class Check {
12525
+ constructor(table, builder) {
12526
+ this.table = table;
12527
+ this.name = builder.name;
12528
+ this.value = builder.value;
12529
+ }
12530
+ static [entityKind] = "PgCheck";
12531
+ name;
12532
+ value;
12533
+ }
12534
+
12443
12535
  // node_modules/drizzle-orm/selection-proxy.js
12444
12536
  class SelectionProxyHandler {
12445
12537
  static [entityKind] = "SelectionProxyHandler";
@@ -14133,6 +14225,69 @@ class PgDatabase {
14133
14225
  }
14134
14226
  }
14135
14227
 
14228
+ // node_modules/drizzle-orm/pg-core/indexes.js
14229
+ class IndexBuilder {
14230
+ static [entityKind] = "PgIndexBuilder";
14231
+ config;
14232
+ constructor(columns, unique, only, name, method = "btree") {
14233
+ this.config = {
14234
+ name,
14235
+ columns,
14236
+ unique,
14237
+ only,
14238
+ method
14239
+ };
14240
+ }
14241
+ concurrently() {
14242
+ this.config.concurrently = true;
14243
+ return this;
14244
+ }
14245
+ with(obj) {
14246
+ this.config.with = obj;
14247
+ return this;
14248
+ }
14249
+ where(condition) {
14250
+ this.config.where = condition;
14251
+ return this;
14252
+ }
14253
+ build(table) {
14254
+ return new Index(this.config, table);
14255
+ }
14256
+ }
14257
+
14258
+ class Index {
14259
+ static [entityKind] = "PgIndex";
14260
+ config;
14261
+ constructor(config, table) {
14262
+ this.config = { ...config, table };
14263
+ }
14264
+ }
14265
+
14266
+ // node_modules/drizzle-orm/pg-core/policies.js
14267
+ class PgPolicy {
14268
+ constructor(name, config) {
14269
+ this.name = name;
14270
+ if (config) {
14271
+ this.as = config.as;
14272
+ this.for = config.for;
14273
+ this.to = config.to;
14274
+ this.using = config.using;
14275
+ this.withCheck = config.withCheck;
14276
+ }
14277
+ }
14278
+ static [entityKind] = "PgPolicy";
14279
+ as;
14280
+ for;
14281
+ to;
14282
+ using;
14283
+ withCheck;
14284
+ _linkedTable;
14285
+ link(table) {
14286
+ this._linkedTable = table;
14287
+ return this;
14288
+ }
14289
+ }
14290
+
14136
14291
  // node_modules/drizzle-orm/pg-core/session.js
14137
14292
  class PgPreparedQuery {
14138
14293
  constructor(query) {
@@ -14175,6 +14330,52 @@ class PgSession {
14175
14330
  }
14176
14331
  }
14177
14332
 
14333
+ // node_modules/drizzle-orm/pg-core/utils.js
14334
+ function getTableConfig(table) {
14335
+ const columns = Object.values(table[Table.Symbol.Columns]);
14336
+ const indexes = [];
14337
+ const checks = [];
14338
+ const primaryKeys = [];
14339
+ const foreignKeys = Object.values(table[PgTable.Symbol.InlineForeignKeys]);
14340
+ const uniqueConstraints = [];
14341
+ const name = table[Table.Symbol.Name];
14342
+ const schema = table[Table.Symbol.Schema];
14343
+ const policies = [];
14344
+ const enableRLS = table[PgTable.Symbol.EnableRLS];
14345
+ const extraConfigBuilder = table[PgTable.Symbol.ExtraConfigBuilder];
14346
+ if (extraConfigBuilder !== undefined) {
14347
+ const extraConfig = extraConfigBuilder(table[Table.Symbol.ExtraConfigColumns]);
14348
+ const extraValues = Array.isArray(extraConfig) ? extraConfig.flat(1) : Object.values(extraConfig);
14349
+ for (const builder of extraValues) {
14350
+ if (is(builder, IndexBuilder)) {
14351
+ indexes.push(builder.build(table));
14352
+ } else if (is(builder, CheckBuilder)) {
14353
+ checks.push(builder.build(table));
14354
+ } else if (is(builder, UniqueConstraintBuilder)) {
14355
+ uniqueConstraints.push(builder.build(table));
14356
+ } else if (is(builder, PrimaryKeyBuilder)) {
14357
+ primaryKeys.push(builder.build(table));
14358
+ } else if (is(builder, ForeignKeyBuilder)) {
14359
+ foreignKeys.push(builder.build(table));
14360
+ } else if (is(builder, PgPolicy)) {
14361
+ policies.push(builder);
14362
+ }
14363
+ }
14364
+ }
14365
+ return {
14366
+ columns,
14367
+ indexes,
14368
+ foreignKeys,
14369
+ checks,
14370
+ primaryKeys,
14371
+ uniqueConstraints,
14372
+ name,
14373
+ schema,
14374
+ policies,
14375
+ enableRLS
14376
+ };
14377
+ }
14378
+
14178
14379
  // node_modules/@neondatabase/serverless/index.mjs
14179
14380
  var vo = Object.create;
14180
14381
  var Te = Object.defineProperty;
@@ -19015,6 +19216,7 @@ var Fn = class Fn2 extends mo.Pool {
19015
19216
  }
19016
19217
  };
19017
19218
  a(Fn, "NeonPool");
19219
+ var Ln = Fn;
19018
19220
  We();
19019
19221
  var kn = xe(ot());
19020
19222
  var export_DatabaseError = kn.DatabaseError;
@@ -22442,302 +22644,344 @@ var createPostgresWarrantStore = (db) => ({
22442
22644
  }).onConflictDoNothing({ target: warrantsTable.id });
22443
22645
  }
22444
22646
  });
22445
- // src/sso/samlIdpRoutes.ts
22446
- import { Elysia as Elysia35, t as t31 } from "elysia";
22447
- var HTTP_BAD_REQUEST3 = 400;
22448
- var HTTP_UNAUTHORIZED3 = 401;
22449
- var HTTP_FOUND2 = 302;
22450
- var HTTP_OK3 = 200;
22451
- var xmlResponse = (body) => new Response(body, {
22452
- headers: { "content-type": "application/samlmetadata+xml" },
22453
- status: HTTP_OK3
22647
+
22648
+ // src/organizations/postgresOrganizationStore.ts
22649
+ var ID_LENGTH10 = 255;
22650
+ var NAME_LENGTH = 255;
22651
+ var STATE_LENGTH = 16;
22652
+ var organizationInvitationsTable = pgTable("auth_organization_invitations", {
22653
+ accepted_at_ms: bigint("accepted_at_ms", { mode: "number" }),
22654
+ created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
22655
+ email: varchar("email", { length: ID_LENGTH10 }).notNull(),
22656
+ expires_at_ms: bigint("expires_at_ms", { mode: "number" }).notNull(),
22657
+ invitation_id: varchar("invitation_id", {
22658
+ length: ID_LENGTH10
22659
+ }).primaryKey(),
22660
+ inviter_user_id: varchar("inviter_user_id", { length: ID_LENGTH10 }),
22661
+ organization_id: varchar("organization_id", {
22662
+ length: ID_LENGTH10
22663
+ }).notNull(),
22664
+ roles: jsonb("roles").$type().notNull().default([]),
22665
+ state: varchar("state", { length: STATE_LENGTH }).$type().notNull().default("pending"),
22666
+ token_hash: varchar("token_hash", { length: ID_LENGTH10 }).notNull().unique()
22454
22667
  });
22455
- var htmlResponse = (body) => new Response(body, {
22456
- headers: { "content-type": "text/html; charset=utf-8" },
22457
- status: HTTP_OK3
22668
+ var organizationMembershipsTable = pgTable("auth_organization_memberships", {
22669
+ created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
22670
+ organization_id: varchar("organization_id", {
22671
+ length: ID_LENGTH10
22672
+ }).notNull(),
22673
+ roles: jsonb("roles").$type().notNull().default([]),
22674
+ status: varchar("status", { length: STATE_LENGTH }).$type().notNull().default("active"),
22675
+ updated_at_ms: bigint("updated_at_ms", { mode: "number" }).notNull(),
22676
+ user_id: varchar("user_id", { length: ID_LENGTH10 }).notNull()
22677
+ }, (table) => [primaryKey({ columns: [table.organization_id, table.user_id] })]);
22678
+ var organizationsTable = pgTable("auth_organizations", {
22679
+ created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
22680
+ metadata: jsonb("metadata").$type(),
22681
+ name: varchar("name", { length: NAME_LENGTH }).notNull(),
22682
+ organization_id: varchar("organization_id", {
22683
+ length: ID_LENGTH10
22684
+ }).primaryKey(),
22685
+ updated_at_ms: bigint("updated_at_ms", { mode: "number" }).notNull()
22458
22686
  });
22459
- var redirectTo2 = (url) => new Response(null, { headers: { location: url }, status: HTTP_FOUND2 });
22460
- var errorJson = (status, error) => new Response(JSON.stringify({ error }), {
22461
- headers: { "content-type": "application/json" },
22462
- status
22687
+ var toOrganization = (row) => ({
22688
+ createdAt: row.created_at_ms,
22689
+ metadata: row.metadata ?? undefined,
22690
+ name: row.name,
22691
+ organizationId: row.organization_id,
22692
+ updatedAt: row.updated_at_ms
22463
22693
  });
22464
- var samlIdpRoutes = ({
22465
- authSessionStore,
22466
- getNameId,
22467
- getSamlAttributes,
22468
- idpAdapter,
22469
- idpEntityId,
22470
- loginUrl,
22471
- samlServiceProviderStore,
22472
- ssoRoute = DEFAULT_SSO_ROUTE
22473
- }) => {
22474
- const ssoIdpRoute = `${ssoRoute}/saml/idp/sso`;
22475
- const idpInitiateRoute = `${ssoRoute}/saml/idp/sso/initiate`;
22476
- const idpMetadataRoute = `${ssoRoute}/saml/idp/metadata`;
22477
- const ssoUrlFor = (requestUrl) => `${new URL(requestUrl).origin}${ssoIdpRoute}`;
22478
- const renderResponse = async ({
22479
- acsUrl,
22480
- inResponseTo,
22481
- relayState,
22482
- serviceProviderEntityId,
22483
- user
22484
- }) => {
22485
- const samlResponse = await idpAdapter.createSamlResponse({
22486
- acsUrl,
22487
- attributes: getSamlAttributes?.(user),
22488
- audience: serviceProviderEntityId,
22489
- idpEntityId,
22490
- inResponseTo,
22491
- nameId: getNameId(user),
22492
- sessionIndex: crypto.randomUUID()
22493
- });
22494
- const html2 = idpAdapter.buildAutoPostForm({
22495
- acsUrl,
22496
- relayState,
22497
- samlResponse
22694
+ var toMembership = (row) => ({
22695
+ createdAt: row.created_at_ms,
22696
+ organizationId: row.organization_id,
22697
+ roles: row.roles,
22698
+ status: row.status,
22699
+ updatedAt: row.updated_at_ms,
22700
+ userId: row.user_id
22701
+ });
22702
+ var toInvitation = (row) => ({
22703
+ acceptedAt: row.accepted_at_ms ?? undefined,
22704
+ createdAt: row.created_at_ms,
22705
+ email: row.email,
22706
+ expiresAt: row.expires_at_ms,
22707
+ invitationId: row.invitation_id,
22708
+ inviterUserId: row.inviter_user_id ?? undefined,
22709
+ organizationId: row.organization_id,
22710
+ roles: row.roles,
22711
+ state: row.state,
22712
+ tokenHash: row.token_hash
22713
+ });
22714
+ var createNeonOrganizationStore = (databaseUrl) => createPostgresOrganizationStore(createNeonDatabase(databaseUrl));
22715
+ var createPostgresOrganizationStore = (db) => ({
22716
+ deleteOrganization: async (organizationId) => {
22717
+ await db.delete(organizationsTable).where(eq(organizationsTable.organization_id, organizationId));
22718
+ },
22719
+ getInvitation: async (invitationId) => {
22720
+ const [row] = await db.select().from(organizationInvitationsTable).where(eq(organizationInvitationsTable.invitation_id, invitationId)).limit(1);
22721
+ return row ? toInvitation(row) : undefined;
22722
+ },
22723
+ getInvitationByTokenHash: async (tokenHash) => {
22724
+ const [row] = await db.select().from(organizationInvitationsTable).where(eq(organizationInvitationsTable.token_hash, tokenHash)).limit(1);
22725
+ return row ? toInvitation(row) : undefined;
22726
+ },
22727
+ getMembership: async (organizationId, userId) => {
22728
+ const [row] = await db.select().from(organizationMembershipsTable).where(and(eq(organizationMembershipsTable.organization_id, organizationId), eq(organizationMembershipsTable.user_id, userId))).limit(1);
22729
+ return row ? toMembership(row) : undefined;
22730
+ },
22731
+ getOrganization: async (organizationId) => {
22732
+ const [row] = await db.select().from(organizationsTable).where(eq(organizationsTable.organization_id, organizationId)).limit(1);
22733
+ return row ? toOrganization(row) : undefined;
22734
+ },
22735
+ listInvitationsByOrganization: async (organizationId) => {
22736
+ const rows = await db.select().from(organizationInvitationsTable).where(eq(organizationInvitationsTable.organization_id, organizationId));
22737
+ return rows.map(toInvitation);
22738
+ },
22739
+ listMembershipsByOrganization: async (organizationId) => {
22740
+ const rows = await db.select().from(organizationMembershipsTable).where(eq(organizationMembershipsTable.organization_id, organizationId));
22741
+ return rows.map(toMembership);
22742
+ },
22743
+ listMembershipsByUser: async (userId) => {
22744
+ const rows = await db.select().from(organizationMembershipsTable).where(eq(organizationMembershipsTable.user_id, userId));
22745
+ return rows.map(toMembership);
22746
+ },
22747
+ removeMembership: async (organizationId, userId) => {
22748
+ await db.delete(organizationMembershipsTable).where(and(eq(organizationMembershipsTable.organization_id, organizationId), eq(organizationMembershipsTable.user_id, userId)));
22749
+ },
22750
+ saveInvitation: async (invitation) => {
22751
+ const values = {
22752
+ accepted_at_ms: invitation.acceptedAt ?? null,
22753
+ created_at_ms: invitation.createdAt,
22754
+ email: invitation.email,
22755
+ expires_at_ms: invitation.expiresAt,
22756
+ invitation_id: invitation.invitationId,
22757
+ inviter_user_id: invitation.inviterUserId ?? null,
22758
+ organization_id: invitation.organizationId,
22759
+ roles: invitation.roles,
22760
+ state: invitation.state,
22761
+ token_hash: invitation.tokenHash
22762
+ };
22763
+ await db.insert(organizationInvitationsTable).values(values).onConflictDoUpdate({
22764
+ set: values,
22765
+ target: organizationInvitationsTable.invitation_id
22498
22766
  });
22499
- return htmlResponse(html2);
22500
- };
22501
- const handleSpInitiated = async ({
22502
- binding,
22503
- body,
22504
- inMemorySession,
22505
- request,
22506
- userSessionIdValue
22507
- }) => {
22508
- if (body.SAMLRequest === undefined) {
22509
- return errorJson(HTTP_BAD_REQUEST3, "missing_saml_request");
22510
- }
22511
- let firstPass;
22512
- try {
22513
- firstPass = await idpAdapter.parseAuthnRequest({
22514
- binding,
22515
- samlRequest: body.SAMLRequest
22516
- });
22517
- } catch {
22518
- return errorJson(HTTP_BAD_REQUEST3, "invalid_authn_request");
22519
- }
22520
- const serviceProvider = await samlServiceProviderStore.findServiceProvider(firstPass.issuer);
22521
- if (serviceProvider === undefined) {
22522
- return errorJson(HTTP_BAD_REQUEST3, "unknown_service_provider");
22523
- }
22524
- let parsed;
22525
- try {
22526
- parsed = await idpAdapter.parseAuthnRequest({
22527
- binding,
22528
- samlRequest: body.SAMLRequest,
22529
- serviceProvider,
22530
- signature: body.Signature,
22531
- signatureAlgorithm: body.SigAlg,
22532
- signedQueryString: binding === "Redirect" ? new URL(request.url).search.slice(1) : undefined
22533
- });
22534
- } catch {
22535
- return errorJson(HTTP_BAD_REQUEST3, "invalid_authn_request");
22536
- }
22537
- const userSession = await loadSessionFromSource({
22538
- authSessionStore,
22539
- session: inMemorySession,
22540
- userSessionId: userSessionIdValue
22541
- });
22542
- if (userSession === undefined || parsed.forceAuthn === true) {
22543
- if (loginUrl === undefined) {
22544
- return errorJson(HTTP_UNAUTHORIZED3, "login_required");
22545
- }
22546
- return redirectTo2(`${loginUrl}?return_to=${encodeURIComponent(request.url)}`);
22547
- }
22548
- return renderResponse({
22549
- acsUrl: parsed.acsUrl ?? serviceProvider.acsUrl,
22550
- inResponseTo: parsed.id,
22551
- relayState: parsed.relayState ?? body.RelayState,
22552
- serviceProviderEntityId: serviceProvider.entityId,
22553
- user: userSession.user
22554
- });
22555
- };
22556
- return new Elysia35().use(sessionStore()).post(ssoIdpRoute, async ({
22557
- body,
22558
- cookie: { user_session_id },
22559
- request,
22560
- store
22561
- }) => handleSpInitiated({
22562
- binding: "POST",
22563
- body,
22564
- inMemorySession: store.session,
22565
- request,
22566
- userSessionIdValue: user_session_id.value
22567
- }), {
22568
- body: t31.Object({
22569
- RelayState: t31.Optional(t31.String()),
22570
- SAMLRequest: t31.Optional(t31.String())
22571
- }),
22572
- cookie: t31.Cookie({
22573
- user_session_id: t31.Optional(userSessionIdTypebox)
22574
- })
22575
- }).get(ssoIdpRoute, async ({
22576
- cookie: { user_session_id },
22577
- query,
22578
- request,
22579
- store
22580
- }) => handleSpInitiated({
22581
- binding: "Redirect",
22582
- body: query,
22583
- inMemorySession: store.session,
22584
- request,
22585
- userSessionIdValue: user_session_id.value
22586
- }), {
22587
- cookie: t31.Cookie({
22588
- user_session_id: t31.Optional(userSessionIdTypebox)
22589
- }),
22590
- query: t31.Object({
22591
- RelayState: t31.Optional(t31.String()),
22592
- SAMLRequest: t31.Optional(t31.String()),
22593
- SigAlg: t31.Optional(t31.String()),
22594
- Signature: t31.Optional(t31.String())
22595
- })
22596
- }).get(idpInitiateRoute, async ({
22597
- cookie: { user_session_id },
22598
- query: { sp: serviceProviderEntityId, RelayState: relayState },
22599
- request,
22600
- store
22601
- }) => {
22602
- if (serviceProviderEntityId === undefined) {
22603
- return errorJson(HTTP_BAD_REQUEST3, "missing_sp");
22604
- }
22605
- const serviceProvider = await samlServiceProviderStore.findServiceProvider(serviceProviderEntityId);
22606
- if (serviceProvider === undefined) {
22607
- return errorJson(HTTP_BAD_REQUEST3, "unknown_service_provider");
22608
- }
22609
- const userSession = authSessionStore === undefined ? await loadSessionFromSource({
22610
- session: store.session,
22611
- userSessionId: user_session_id.value
22612
- }) : await loadSessionFromSource({
22613
- authSessionStore,
22614
- session: store.session,
22615
- userSessionId: user_session_id.value
22616
- });
22617
- if (userSession === undefined) {
22618
- if (loginUrl === undefined) {
22619
- return errorJson(HTTP_UNAUTHORIZED3, "login_required");
22620
- }
22621
- return redirectTo2(`${loginUrl}?return_to=${encodeURIComponent(request.url)}`);
22622
- }
22623
- return renderResponse({
22624
- acsUrl: serviceProvider.acsUrl,
22625
- relayState,
22626
- serviceProviderEntityId: serviceProvider.entityId,
22627
- user: userSession.user
22628
- });
22629
- }, {
22630
- cookie: t31.Cookie({
22631
- user_session_id: t31.Optional(userSessionIdTypebox)
22632
- }),
22633
- query: t31.Object({
22634
- RelayState: t31.Optional(t31.String()),
22635
- sp: t31.Optional(t31.String())
22636
- })
22637
- }).get(idpMetadataRoute, async ({ request }) => xmlResponse(await idpAdapter.getIdpMetadata({
22638
- entityId: idpEntityId,
22639
- ssoUrl: ssoUrlFor(request.url)
22640
- })));
22641
- };
22642
- // src/sso/inMemorySamlServiceProviderStore.ts
22643
- var createInMemorySamlServiceProviderStore = () => {
22644
- const providers2 = new Map;
22645
- return {
22646
- deleteServiceProvider: async (entityId) => {
22647
- providers2.delete(entityId);
22648
- },
22649
- findServiceProvider: async (entityId) => {
22650
- const found = providers2.get(entityId);
22651
- return found ? { ...found } : undefined;
22652
- },
22653
- listServiceProviders: async () => Array.from(providers2.values()).map((serviceProvider) => ({ ...serviceProvider })),
22654
- saveServiceProvider: async (serviceProvider) => {
22655
- providers2.set(serviceProvider.entityId, { ...serviceProvider });
22656
- }
22657
- };
22658
- };
22659
- // src/sso/inMemorySsoConnectionStore.ts
22660
- var cloneConnection = (value) => value.type === "oidc" ? {
22661
- ...value,
22662
- config: { ...value.config, scopes: [...value.config.scopes] }
22663
- } : { ...value, config: { ...value.config } };
22664
- var createInMemorySsoConnectionStore = () => {
22665
- const connections = new Map;
22666
- return {
22667
- deleteConnection: async (connectionId) => {
22668
- connections.delete(connectionId);
22669
- },
22670
- getConnection: async (connectionId) => {
22671
- const connection = connections.get(connectionId);
22672
- return connection ? cloneConnection(connection) : undefined;
22673
- },
22674
- getConnectionByOrganization: async (organizationId, type) => {
22675
- const match = Array.from(connections.values()).find((connection) => connection.organizationId === organizationId && connection.enabled && (type === undefined || connection.type === type));
22676
- return match ? cloneConnection(match) : undefined;
22677
- },
22678
- listConnectionsByOrganization: async (organizationId) => Array.from(connections.values()).filter((connection) => connection.organizationId === organizationId).sort((left, right) => right.updatedAt - left.updatedAt).map(cloneConnection),
22679
- saveConnection: async (connection) => {
22680
- connections.set(connection.connectionId, cloneConnection(connection));
22681
- }
22682
- };
22683
- };
22684
- // src/sso/postgresSamlServiceProviderStore.ts
22685
- var ID_LENGTH10 = 255;
22686
- var URL_LENGTH2 = 2048;
22687
- var samlServiceProvidersTable = pgTable("auth_saml_service_providers", {
22688
- acs_url: varchar("acs_url", { length: URL_LENGTH2 }).notNull(),
22689
- created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
22690
- entity_id: varchar("entity_id", { length: URL_LENGTH2 }).primaryKey(),
22691
- name_id_format: varchar("name_id_format", { length: ID_LENGTH10 }),
22692
- signing_cert: text("signing_cert"),
22693
- updated_at_ms: bigint("updated_at_ms", { mode: "number" }).notNull()
22694
- });
22695
- var toServiceProvider = (row) => ({
22696
- acsUrl: row.acs_url,
22697
- createdAt: row.created_at_ms,
22698
- entityId: row.entity_id,
22699
- nameIdFormat: row.name_id_format ?? undefined,
22700
- signingCert: row.signing_cert ?? undefined,
22701
- updatedAt: row.updated_at_ms
22702
- });
22703
- var toValues2 = (serviceProvider) => ({
22704
- acs_url: serviceProvider.acsUrl,
22705
- created_at_ms: serviceProvider.createdAt,
22706
- entity_id: serviceProvider.entityId,
22707
- name_id_format: serviceProvider.nameIdFormat ?? null,
22708
- signing_cert: serviceProvider.signingCert ?? null,
22709
- updated_at_ms: serviceProvider.updatedAt
22710
- });
22711
- var createNeonSamlServiceProviderStore = (databaseUrl) => createPostgresSamlServiceProviderStore(createNeonDatabase(databaseUrl));
22712
- var createPostgresSamlServiceProviderStore = (db) => ({
22713
- deleteServiceProvider: async (entityId) => {
22714
- await db.delete(samlServiceProvidersTable).where(eq(samlServiceProvidersTable.entity_id, entityId));
22715
- },
22716
- findServiceProvider: async (entityId) => {
22717
- const [row] = await db.select().from(samlServiceProvidersTable).where(eq(samlServiceProvidersTable.entity_id, entityId)).limit(1);
22718
- return row === undefined ? undefined : toServiceProvider(row);
22719
22767
  },
22720
- listServiceProviders: async () => {
22721
- const rows = await db.select().from(samlServiceProvidersTable);
22722
- return rows.map(toServiceProvider);
22768
+ saveMembership: async (membership) => {
22769
+ const values = {
22770
+ created_at_ms: membership.createdAt,
22771
+ organization_id: membership.organizationId,
22772
+ roles: membership.roles,
22773
+ status: membership.status,
22774
+ updated_at_ms: membership.updatedAt,
22775
+ user_id: membership.userId
22776
+ };
22777
+ await db.insert(organizationMembershipsTable).values(values).onConflictDoUpdate({
22778
+ set: values,
22779
+ target: [
22780
+ organizationMembershipsTable.organization_id,
22781
+ organizationMembershipsTable.user_id
22782
+ ]
22783
+ });
22723
22784
  },
22724
- saveServiceProvider: async (serviceProvider) => {
22725
- await db.insert(samlServiceProvidersTable).values(toValues2(serviceProvider)).onConflictDoUpdate({
22726
- set: toValues2(serviceProvider),
22727
- target: samlServiceProvidersTable.entity_id
22785
+ saveOrganization: async (organization) => {
22786
+ const values = {
22787
+ created_at_ms: organization.createdAt,
22788
+ metadata: organization.metadata ?? null,
22789
+ name: organization.name,
22790
+ organization_id: organization.organizationId,
22791
+ updated_at_ms: organization.updatedAt
22792
+ };
22793
+ await db.insert(organizationsTable).values(values).onConflictDoUpdate({
22794
+ set: values,
22795
+ target: organizationsTable.organization_id
22728
22796
  });
22729
22797
  }
22730
22798
  });
22731
- // src/sso/postgresSsoConnectionStore.ts
22799
+
22800
+ // src/passwordless/postgresPasswordlessTokenStore.ts
22732
22801
  var ID_LENGTH11 = 255;
22802
+ var passwordlessTokensTable = pgTable("auth_passwordless_tokens", {
22803
+ email: varchar("email", { length: ID_LENGTH11 }).notNull(),
22804
+ expires_at_ms: bigint("expires_at_ms", { mode: "number" }).notNull(),
22805
+ token_hash: varchar("token_hash", { length: ID_LENGTH11 }).primaryKey()
22806
+ });
22807
+ var toToken3 = (row) => ({
22808
+ email: row.email,
22809
+ expiresAt: row.expires_at_ms,
22810
+ tokenHash: row.token_hash
22811
+ });
22812
+ var createNeonPasswordlessTokenStore = (databaseUrl) => createPostgresPasswordlessTokenStore(createNeonDatabase(databaseUrl));
22813
+ var createPostgresPasswordlessTokenStore = (db) => ({
22814
+ consumeToken: async (tokenHash) => {
22815
+ const [row] = await db.delete(passwordlessTokensTable).where(eq(passwordlessTokensTable.token_hash, tokenHash)).returning();
22816
+ return row ? toToken3(row) : undefined;
22817
+ },
22818
+ saveToken: async (token) => {
22819
+ const values = {
22820
+ email: token.email,
22821
+ expires_at_ms: token.expiresAt,
22822
+ token_hash: token.tokenHash
22823
+ };
22824
+ await db.insert(passwordlessTokensTable).values(values).onConflictDoUpdate({
22825
+ set: values,
22826
+ target: passwordlessTokensTable.token_hash
22827
+ });
22828
+ }
22829
+ });
22830
+
22831
+ // src/portal/postgresSetupSessionStore.ts
22832
+ var ID_LENGTH12 = 255;
22833
+ var setupSessionsTable = pgTable("auth_setup_sessions", {
22834
+ capabilities: jsonb("capabilities").$type().notNull().default([]),
22835
+ created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
22836
+ created_by: varchar("created_by", { length: ID_LENGTH12 }),
22837
+ expires_at_ms: bigint("expires_at_ms", { mode: "number" }).notNull(),
22838
+ organization_id: varchar("organization_id", {
22839
+ length: ID_LENGTH12
22840
+ }).notNull(),
22841
+ setup_session_id: varchar("setup_session_id", {
22842
+ length: ID_LENGTH12
22843
+ }).primaryKey(),
22844
+ token_hash: varchar("token_hash", { length: ID_LENGTH12 }).notNull().unique()
22845
+ });
22846
+ var toSession = (row) => ({
22847
+ capabilities: row.capabilities,
22848
+ createdAt: row.created_at_ms,
22849
+ createdBy: row.created_by ?? undefined,
22850
+ expiresAt: row.expires_at_ms,
22851
+ organizationId: row.organization_id,
22852
+ setupSessionId: row.setup_session_id,
22853
+ tokenHash: row.token_hash
22854
+ });
22855
+ var createNeonSetupSessionStore = (databaseUrl) => createPostgresSetupSessionStore(createNeonDatabase(databaseUrl));
22856
+ var createPostgresSetupSessionStore = (db) => ({
22857
+ deleteSetupSession: async (setupSessionId) => {
22858
+ await db.delete(setupSessionsTable).where(eq(setupSessionsTable.setup_session_id, setupSessionId));
22859
+ },
22860
+ getSetupSessionByTokenHash: async (tokenHash) => {
22861
+ const [row] = await db.select().from(setupSessionsTable).where(eq(setupSessionsTable.token_hash, tokenHash)).limit(1);
22862
+ return row ? toSession(row) : undefined;
22863
+ },
22864
+ saveSetupSession: async (session) => {
22865
+ const values = {
22866
+ capabilities: session.capabilities,
22867
+ created_at_ms: session.createdAt,
22868
+ created_by: session.createdBy ?? null,
22869
+ expires_at_ms: session.expiresAt,
22870
+ organization_id: session.organizationId,
22871
+ setup_session_id: session.setupSessionId,
22872
+ token_hash: session.tokenHash
22873
+ };
22874
+ await db.insert(setupSessionsTable).values(values).onConflictDoUpdate({
22875
+ set: values,
22876
+ target: setupSessionsTable.setup_session_id
22877
+ });
22878
+ }
22879
+ });
22880
+
22881
+ // src/roles/postgresRoleStore.ts
22882
+ var ID_LENGTH13 = 255;
22883
+ var SLUG_LENGTH = 128;
22884
+ var GLOBAL_SCOPE = "";
22885
+ var rolesTable = pgTable("auth_roles", {
22886
+ created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
22887
+ organization_id: varchar("organization_id", { length: ID_LENGTH13 }).notNull().default(GLOBAL_SCOPE),
22888
+ permissions: jsonb("permissions").$type().notNull().default([]),
22889
+ slug: varchar("slug", { length: SLUG_LENGTH }).notNull(),
22890
+ updated_at_ms: bigint("updated_at_ms", { mode: "number" }).notNull()
22891
+ }, (table) => [primaryKey({ columns: [table.organization_id, table.slug] })]);
22892
+ var toRole = (row) => ({
22893
+ createdAt: row.created_at_ms,
22894
+ organizationId: row.organization_id === GLOBAL_SCOPE ? undefined : row.organization_id,
22895
+ permissions: row.permissions,
22896
+ slug: row.slug,
22897
+ updatedAt: row.updated_at_ms
22898
+ });
22899
+ var createNeonRoleStore = (databaseUrl) => createPostgresRoleStore(createNeonDatabase(databaseUrl));
22900
+ var createPostgresRoleStore = (db) => ({
22901
+ deleteRole: async (slug, organizationId) => {
22902
+ await db.delete(rolesTable).where(and(eq(rolesTable.organization_id, organizationId ?? GLOBAL_SCOPE), eq(rolesTable.slug, slug)));
22903
+ },
22904
+ getRole: async (slug, organizationId) => {
22905
+ const [row] = await db.select().from(rolesTable).where(and(eq(rolesTable.organization_id, organizationId ?? GLOBAL_SCOPE), eq(rolesTable.slug, slug))).limit(1);
22906
+ return row ? toRole(row) : undefined;
22907
+ },
22908
+ listRoles: async (organizationId) => {
22909
+ const rows = await db.select().from(rolesTable).where(eq(rolesTable.organization_id, organizationId ?? GLOBAL_SCOPE));
22910
+ return rows.map(toRole);
22911
+ },
22912
+ saveRole: async (role) => {
22913
+ const values = {
22914
+ created_at_ms: role.createdAt,
22915
+ organization_id: role.organizationId ?? GLOBAL_SCOPE,
22916
+ permissions: role.permissions,
22917
+ slug: role.slug,
22918
+ updated_at_ms: role.updatedAt
22919
+ };
22920
+ await db.insert(rolesTable).values(values).onConflictDoUpdate({
22921
+ set: values,
22922
+ target: [rolesTable.organization_id, rolesTable.slug]
22923
+ });
22924
+ }
22925
+ });
22926
+
22927
+ // src/sso/postgresSamlServiceProviderStore.ts
22928
+ var ID_LENGTH14 = 255;
22929
+ var URL_LENGTH2 = 2048;
22930
+ var samlServiceProvidersTable = pgTable("auth_saml_service_providers", {
22931
+ acs_url: varchar("acs_url", { length: URL_LENGTH2 }).notNull(),
22932
+ created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
22933
+ entity_id: varchar("entity_id", { length: URL_LENGTH2 }).primaryKey(),
22934
+ name_id_format: varchar("name_id_format", { length: ID_LENGTH14 }),
22935
+ signing_cert: text("signing_cert"),
22936
+ updated_at_ms: bigint("updated_at_ms", { mode: "number" }).notNull()
22937
+ });
22938
+ var toServiceProvider = (row) => ({
22939
+ acsUrl: row.acs_url,
22940
+ createdAt: row.created_at_ms,
22941
+ entityId: row.entity_id,
22942
+ nameIdFormat: row.name_id_format ?? undefined,
22943
+ signingCert: row.signing_cert ?? undefined,
22944
+ updatedAt: row.updated_at_ms
22945
+ });
22946
+ var toValues2 = (serviceProvider) => ({
22947
+ acs_url: serviceProvider.acsUrl,
22948
+ created_at_ms: serviceProvider.createdAt,
22949
+ entity_id: serviceProvider.entityId,
22950
+ name_id_format: serviceProvider.nameIdFormat ?? null,
22951
+ signing_cert: serviceProvider.signingCert ?? null,
22952
+ updated_at_ms: serviceProvider.updatedAt
22953
+ });
22954
+ var createNeonSamlServiceProviderStore = (databaseUrl) => createPostgresSamlServiceProviderStore(createNeonDatabase(databaseUrl));
22955
+ var createPostgresSamlServiceProviderStore = (db) => ({
22956
+ deleteServiceProvider: async (entityId) => {
22957
+ await db.delete(samlServiceProvidersTable).where(eq(samlServiceProvidersTable.entity_id, entityId));
22958
+ },
22959
+ findServiceProvider: async (entityId) => {
22960
+ const [row] = await db.select().from(samlServiceProvidersTable).where(eq(samlServiceProvidersTable.entity_id, entityId)).limit(1);
22961
+ return row === undefined ? undefined : toServiceProvider(row);
22962
+ },
22963
+ listServiceProviders: async () => {
22964
+ const rows = await db.select().from(samlServiceProvidersTable);
22965
+ return rows.map(toServiceProvider);
22966
+ },
22967
+ saveServiceProvider: async (serviceProvider) => {
22968
+ await db.insert(samlServiceProvidersTable).values(toValues2(serviceProvider)).onConflictDoUpdate({
22969
+ set: toValues2(serviceProvider),
22970
+ target: samlServiceProvidersTable.entity_id
22971
+ });
22972
+ }
22973
+ });
22974
+
22975
+ // src/sso/postgresSsoConnectionStore.ts
22976
+ var ID_LENGTH15 = 255;
22733
22977
  var TYPE_LENGTH2 = 16;
22734
22978
  var ssoConnectionsTable = pgTable("auth_sso_connections", {
22735
22979
  config: jsonb("config").$type().notNull(),
22736
- connection_id: varchar("connection_id", { length: ID_LENGTH11 }).primaryKey(),
22980
+ connection_id: varchar("connection_id", { length: ID_LENGTH15 }).primaryKey(),
22737
22981
  created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
22738
22982
  enabled: boolean("enabled").notNull().default(true),
22739
22983
  organization_id: varchar("organization_id", {
22740
- length: ID_LENGTH11
22984
+ length: ID_LENGTH15
22741
22985
  }).notNull(),
22742
22986
  type: varchar("type", { length: TYPE_LENGTH2 }).$type().notNull(),
22743
22987
  updated_at_ms: bigint("updated_at_ms", { mode: "number" }).notNull()
@@ -22841,40 +23085,20 @@ var createPostgresSsoConnectionStore = (db) => ({
22841
23085
  });
22842
23086
  }
22843
23087
  });
22844
- // src/webauthn/inMemoryWebAuthnCredentialStore.ts
22845
- var cloneCredential2 = (value) => ({
22846
- ...value,
22847
- transports: value.transports ? [...value.transports] : undefined
22848
- });
22849
- var createInMemoryWebAuthnCredentialStore = () => {
22850
- const credentials = new Map;
22851
- return {
22852
- getCredential: async (credentialId) => {
22853
- const credential = credentials.get(credentialId);
22854
- return credential ? cloneCredential2(credential) : undefined;
22855
- },
22856
- listCredentialsByUser: async (userId) => [...credentials.values()].filter((credential) => credential.userId === userId).map(cloneCredential2),
22857
- removeCredential: async (credentialId) => {
22858
- credentials.delete(credentialId);
22859
- },
22860
- saveCredential: async (credential) => {
22861
- credentials.set(credential.credentialId, cloneCredential2(credential));
22862
- }
22863
- };
22864
- };
23088
+
22865
23089
  // src/webauthn/postgresWebAuthnCredentialStore.ts
22866
- var ID_LENGTH12 = 255;
23090
+ var ID_LENGTH16 = 255;
22867
23091
  var DEVICE_TYPE_LENGTH = 32;
22868
23092
  var webauthnCredentialsTable = pgTable("auth_webauthn_credentials", {
22869
23093
  backed_up: boolean("backed_up"),
22870
23094
  counter: bigint("counter", { mode: "number" }).notNull().default(0),
22871
23095
  created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
22872
- credential_id: varchar("credential_id", { length: ID_LENGTH12 }).primaryKey(),
23096
+ credential_id: varchar("credential_id", { length: ID_LENGTH16 }).primaryKey(),
22873
23097
  device_type: varchar("device_type", { length: DEVICE_TYPE_LENGTH }),
22874
23098
  last_used_at_ms: bigint("last_used_at_ms", { mode: "number" }),
22875
23099
  public_key: text("public_key").notNull(),
22876
23100
  transports: jsonb("transports").$type(),
22877
- user_id: varchar("user_id", { length: ID_LENGTH12 }).notNull()
23101
+ user_id: varchar("user_id", { length: ID_LENGTH16 }).notNull()
22878
23102
  });
22879
23103
  var toCredential = (row) => ({
22880
23104
  backedUp: row.backed_up ?? undefined,
@@ -22919,204 +23143,514 @@ var createPostgresWebAuthnCredentialStore = (db) => ({
22919
23143
  });
22920
23144
  }
22921
23145
  });
22922
- // src/organizations/inMemoryOrganizationStore.ts
22923
- var membershipKey = (organizationId, userId) => `${organizationId}\x00${userId}`;
22924
- var cloneMembership = (value) => ({ ...value, roles: [...value.roles] });
22925
- var cloneInvitation = (value) => ({ ...value, roles: [...value.roles] });
22926
- var createInMemoryOrganizationStore = () => {
22927
- const organizations = new Map;
22928
- const memberships = new Map;
22929
- const invitations = new Map;
22930
- return {
22931
- deleteOrganization: async (organizationId) => {
22932
- organizations.delete(organizationId);
22933
- },
22934
- getInvitation: async (invitationId) => {
22935
- const invitation = invitations.get(invitationId);
22936
- return invitation ? cloneInvitation(invitation) : undefined;
22937
- },
22938
- getInvitationByTokenHash: async (tokenHash) => {
22939
- const invitation = [...invitations.values()].find((entry) => entry.tokenHash === tokenHash);
22940
- return invitation ? cloneInvitation(invitation) : undefined;
22941
- },
22942
- getMembership: async (organizationId, userId) => {
22943
- const membership = memberships.get(membershipKey(organizationId, userId));
22944
- return membership ? cloneMembership(membership) : undefined;
22945
- },
22946
- getOrganization: async (organizationId) => {
22947
- const organization = organizations.get(organizationId);
22948
- return organization ? { ...organization } : undefined;
22949
- },
22950
- listInvitationsByOrganization: async (organizationId) => [...invitations.values()].filter((entry) => entry.organizationId === organizationId).map(cloneInvitation),
22951
- listMembershipsByOrganization: async (organizationId) => [...memberships.values()].filter((entry) => entry.organizationId === organizationId).map(cloneMembership),
22952
- listMembershipsByUser: async (userId) => [...memberships.values()].filter((entry) => entry.userId === userId).map(cloneMembership),
22953
- removeMembership: async (organizationId, userId) => {
22954
- memberships.delete(membershipKey(organizationId, userId));
22955
- },
22956
- saveInvitation: async (invitation) => {
22957
- invitations.set(invitation.invitationId, cloneInvitation(invitation));
22958
- },
22959
- saveMembership: async (membership) => {
22960
- memberships.set(membershipKey(membership.organizationId, membership.userId), cloneMembership(membership));
22961
- },
22962
- saveOrganization: async (organization) => {
22963
- organizations.set(organization.organizationId, {
22964
- ...organization
22965
- });
22966
- }
22967
- };
22968
- };
22969
- // src/organizations/postgresOrganizationStore.ts
22970
- var ID_LENGTH13 = 255;
22971
- var NAME_LENGTH = 255;
22972
- var STATE_LENGTH = 16;
22973
- var organizationInvitationsTable = pgTable("auth_organization_invitations", {
22974
- accepted_at_ms: bigint("accepted_at_ms", { mode: "number" }),
23146
+
23147
+ // src/webhooks/postgresStore.ts
23148
+ var ID_LENGTH17 = 255;
23149
+ var URL_LENGTH3 = 2048;
23150
+ var DEFAULT_LIST_LIMIT3 = 100;
23151
+ var webhookDeliveriesTable = pgTable("auth_webhook_deliveries", {
23152
+ attempts: bigint("attempts", { mode: "number" }).notNull(),
22975
23153
  created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
22976
- email: varchar("email", { length: ID_LENGTH13 }).notNull(),
22977
- expires_at_ms: bigint("expires_at_ms", { mode: "number" }).notNull(),
22978
- invitation_id: varchar("invitation_id", {
22979
- length: ID_LENGTH13
22980
- }).primaryKey(),
22981
- inviter_user_id: varchar("inviter_user_id", { length: ID_LENGTH13 }),
22982
- organization_id: varchar("organization_id", {
22983
- length: ID_LENGTH13
22984
- }).notNull(),
22985
- roles: jsonb("roles").$type().notNull().default([]),
22986
- state: varchar("state", { length: STATE_LENGTH }).$type().notNull().default("pending"),
22987
- token_hash: varchar("token_hash", { length: ID_LENGTH13 }).notNull().unique()
22988
- });
22989
- var organizationMembershipsTable = pgTable("auth_organization_memberships", {
22990
- created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
22991
- organization_id: varchar("organization_id", {
22992
- length: ID_LENGTH13
22993
- }).notNull(),
22994
- roles: jsonb("roles").$type().notNull().default([]),
22995
- status: varchar("status", { length: STATE_LENGTH }).$type().notNull().default("active"),
22996
- updated_at_ms: bigint("updated_at_ms", { mode: "number" }).notNull(),
22997
- user_id: varchar("user_id", { length: ID_LENGTH13 }).notNull()
22998
- }, (table) => [primaryKey({ columns: [table.organization_id, table.user_id] })]);
22999
- var organizationsTable = pgTable("auth_organizations", {
23000
- created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
23001
- metadata: jsonb("metadata").$type(),
23002
- name: varchar("name", { length: NAME_LENGTH }).notNull(),
23003
- organization_id: varchar("organization_id", {
23004
- length: ID_LENGTH13
23005
- }).primaryKey(),
23006
- updated_at_ms: bigint("updated_at_ms", { mode: "number" }).notNull()
23007
- });
23008
- var toOrganization = (row) => ({
23009
- createdAt: row.created_at_ms,
23010
- metadata: row.metadata ?? undefined,
23011
- name: row.name,
23012
- organizationId: row.organization_id,
23013
- updatedAt: row.updated_at_ms
23014
- });
23015
- var toMembership = (row) => ({
23016
- createdAt: row.created_at_ms,
23017
- organizationId: row.organization_id,
23018
- roles: row.roles,
23019
- status: row.status,
23020
- updatedAt: row.updated_at_ms,
23021
- userId: row.user_id
23154
+ endpoint_url: varchar("endpoint_url", { length: URL_LENGTH3 }).notNull(),
23155
+ envelope_id: varchar("envelope_id", { length: ID_LENGTH17 }).primaryKey(),
23156
+ envelope_json: jsonb("envelope_json").$type().notNull(),
23157
+ last_error: text("last_error"),
23158
+ last_status: bigint("last_status", { mode: "number" })
23022
23159
  });
23023
- var toInvitation = (row) => ({
23024
- acceptedAt: row.accepted_at_ms ?? undefined,
23160
+ var toDelivery = (row) => ({
23161
+ attempts: row.attempts,
23025
23162
  createdAt: row.created_at_ms,
23026
- email: row.email,
23027
- expiresAt: row.expires_at_ms,
23028
- invitationId: row.invitation_id,
23029
- inviterUserId: row.inviter_user_id ?? undefined,
23030
- organizationId: row.organization_id,
23031
- roles: row.roles,
23032
- state: row.state,
23033
- tokenHash: row.token_hash
23163
+ endpointUrl: row.endpoint_url,
23164
+ envelope: row.envelope_json,
23165
+ lastError: row.last_error ?? undefined,
23166
+ lastStatus: row.last_status ?? undefined
23034
23167
  });
23035
- var createNeonOrganizationStore = (databaseUrl) => createPostgresOrganizationStore(createNeonDatabase(databaseUrl));
23036
- var createPostgresOrganizationStore = (db) => ({
23037
- deleteOrganization: async (organizationId) => {
23038
- await db.delete(organizationsTable).where(eq(organizationsTable.organization_id, organizationId));
23039
- },
23040
- getInvitation: async (invitationId) => {
23041
- const [row] = await db.select().from(organizationInvitationsTable).where(eq(organizationInvitationsTable.invitation_id, invitationId)).limit(1);
23042
- return row ? toInvitation(row) : undefined;
23043
- },
23044
- getInvitationByTokenHash: async (tokenHash) => {
23045
- const [row] = await db.select().from(organizationInvitationsTable).where(eq(organizationInvitationsTable.token_hash, tokenHash)).limit(1);
23046
- return row ? toInvitation(row) : undefined;
23047
- },
23048
- getMembership: async (organizationId, userId) => {
23049
- const [row] = await db.select().from(organizationMembershipsTable).where(and(eq(organizationMembershipsTable.organization_id, organizationId), eq(organizationMembershipsTable.user_id, userId))).limit(1);
23050
- return row ? toMembership(row) : undefined;
23051
- },
23052
- getOrganization: async (organizationId) => {
23053
- const [row] = await db.select().from(organizationsTable).where(eq(organizationsTable.organization_id, organizationId)).limit(1);
23054
- return row ? toOrganization(row) : undefined;
23055
- },
23056
- listInvitationsByOrganization: async (organizationId) => {
23057
- const rows = await db.select().from(organizationInvitationsTable).where(eq(organizationInvitationsTable.organization_id, organizationId));
23058
- return rows.map(toInvitation);
23059
- },
23060
- listMembershipsByOrganization: async (organizationId) => {
23061
- const rows = await db.select().from(organizationMembershipsTable).where(eq(organizationMembershipsTable.organization_id, organizationId));
23062
- return rows.map(toMembership);
23063
- },
23064
- listMembershipsByUser: async (userId) => {
23065
- const rows = await db.select().from(organizationMembershipsTable).where(eq(organizationMembershipsTable.user_id, userId));
23066
- return rows.map(toMembership);
23067
- },
23068
- removeMembership: async (organizationId, userId) => {
23069
- await db.delete(organizationMembershipsTable).where(and(eq(organizationMembershipsTable.organization_id, organizationId), eq(organizationMembershipsTable.user_id, userId)));
23168
+ var createNeonWebhookDeliveryStore = (databaseUrl) => createPostgresWebhookDeliveryStore(createNeonDatabase(databaseUrl));
23169
+ var createPostgresWebhookDeliveryStore = (db) => ({
23170
+ listFailed: async (limit = DEFAULT_LIST_LIMIT3) => {
23171
+ const rows = await db.select().from(webhookDeliveriesTable).orderBy(desc(webhookDeliveriesTable.created_at_ms)).limit(limit);
23172
+ return rows.map(toDelivery);
23070
23173
  },
23071
- saveInvitation: async (invitation) => {
23072
- const values = {
23073
- accepted_at_ms: invitation.acceptedAt ?? null,
23074
- created_at_ms: invitation.createdAt,
23075
- email: invitation.email,
23076
- expires_at_ms: invitation.expiresAt,
23077
- invitation_id: invitation.invitationId,
23078
- inviter_user_id: invitation.inviterUserId ?? null,
23079
- organization_id: invitation.organizationId,
23080
- roles: invitation.roles,
23081
- state: invitation.state,
23082
- token_hash: invitation.tokenHash
23083
- };
23084
- await db.insert(organizationInvitationsTable).values(values).onConflictDoUpdate({
23085
- set: values,
23086
- target: organizationInvitationsTable.invitation_id
23174
+ recordFailure: async (delivery) => {
23175
+ await db.insert(webhookDeliveriesTable).values({
23176
+ attempts: delivery.attempts,
23177
+ created_at_ms: delivery.createdAt,
23178
+ endpoint_url: delivery.endpointUrl,
23179
+ envelope_id: delivery.envelope.id,
23180
+ envelope_json: delivery.envelope,
23181
+ last_error: delivery.lastError ?? null,
23182
+ last_status: delivery.lastStatus ?? null
23087
23183
  });
23088
23184
  },
23089
- saveMembership: async (membership) => {
23090
- const values = {
23091
- created_at_ms: membership.createdAt,
23092
- organization_id: membership.organizationId,
23093
- roles: membership.roles,
23094
- status: membership.status,
23095
- updated_at_ms: membership.updatedAt,
23096
- user_id: membership.userId
23097
- };
23098
- await db.insert(organizationMembershipsTable).values(values).onConflictDoUpdate({
23099
- set: values,
23100
- target: [
23101
- organizationMembershipsTable.organization_id,
23102
- organizationMembershipsTable.user_id
23103
- ]
23185
+ removeFailure: async (envelopeId) => {
23186
+ await db.delete(webhookDeliveriesTable).where(eq(webhookDeliveriesTable.envelope_id, envelopeId));
23187
+ }
23188
+ });
23189
+
23190
+ // src/migrations/generate.ts
23191
+ var renderChunk = (chunk) => {
23192
+ if (chunk === null || typeof chunk !== "object")
23193
+ return String(chunk);
23194
+ const value = Reflect.get(chunk, "value");
23195
+ if (Array.isArray(value))
23196
+ return value.map((part) => String(part)).join("");
23197
+ return "";
23198
+ };
23199
+ var formatSqlTemplate = (value) => value.queryChunks.map(renderChunk).join("");
23200
+ var formatDefault = (value) => {
23201
+ if (value === null || value === undefined)
23202
+ return "NULL";
23203
+ if (is(value, SQL))
23204
+ return formatSqlTemplate(value);
23205
+ if (typeof value === "string")
23206
+ return `'${value.replace(/'/gu, "''")}'`;
23207
+ if (typeof value === "boolean")
23208
+ return value ? "true" : "false";
23209
+ if (typeof value === "number")
23210
+ return String(value);
23211
+ if (Array.isArray(value) || typeof value === "object") {
23212
+ return `'${JSON.stringify(value)}'::jsonb`;
23213
+ }
23214
+ return String(value);
23215
+ };
23216
+ var columnSql = (column) => {
23217
+ const parts = [`"${column.name}"`, column.getSQLType()];
23218
+ if (column.primary)
23219
+ parts.push("PRIMARY KEY");
23220
+ if (column.notNull && !column.primary)
23221
+ parts.push("NOT NULL");
23222
+ if (column.hasDefault && column.default !== undefined) {
23223
+ parts.push(`DEFAULT ${formatDefault(column.default)}`);
23224
+ }
23225
+ if (column.isUnique)
23226
+ parts.push("UNIQUE");
23227
+ return parts.join(" ");
23228
+ };
23229
+ var compositePkLine = (compositePk) => `PRIMARY KEY (${compositePk.map((column) => `"${column.name}"`).join(", ")})`;
23230
+ var tableToCreateSql = (table) => {
23231
+ const cfg = getTableConfig(table);
23232
+ const columnLines = cfg.columns.map(columnSql);
23233
+ const singlePk = cfg.columns.find((column) => column.primary);
23234
+ const compositePk = cfg.primaryKeys[0]?.columns ?? [];
23235
+ const lines = singlePk === undefined && compositePk.length > 0 ? [...columnLines, compositePkLine(compositePk)] : columnLines;
23236
+ const body = lines.map((line2) => ` ${line2}`).join(`,
23237
+ `);
23238
+ return `CREATE TABLE IF NOT EXISTS "${cfg.name}" (
23239
+ ${body}
23240
+ );`;
23241
+ };
23242
+ var tablesToInitSql = (tables) => tables.map(tableToCreateSql).join(`
23243
+
23244
+ `);
23245
+
23246
+ // src/migrations/runner.ts
23247
+ var JOURNAL_DDL = `CREATE TABLE IF NOT EXISTS "auth_migrations" (
23248
+ "id" text PRIMARY KEY,
23249
+ "applied_at_ms" bigint NOT NULL
23250
+ );`;
23251
+ var isJournalRow = (value) => typeof value === "object" && value !== null && typeof Reflect.get(value, "id") === "string";
23252
+ var allBlockNames = () => Object.keys(blockMigrations);
23253
+ var applyOne = async (pool, id, sql2, log) => {
23254
+ await pool.query(sql2);
23255
+ await pool.query(`INSERT INTO "auth_migrations" ("id", "applied_at_ms") VALUES ($1, $2)`, [id, Date.now()]);
23256
+ log(`apply ${id}`);
23257
+ };
23258
+ var runOne = async (pool, id, sql2, applied, result, log) => {
23259
+ if (applied.has(id)) {
23260
+ result.skipped.push(id);
23261
+ log(`skip ${id}`);
23262
+ return;
23263
+ }
23264
+ await applyOne(pool, id, sql2, log);
23265
+ result.applied.push(id);
23266
+ };
23267
+ var runMigrations = async ({
23268
+ blocks,
23269
+ databaseUrl,
23270
+ log = console.log
23271
+ }) => {
23272
+ const pool = new Ln({ connectionString: databaseUrl });
23273
+ const result = { applied: [], skipped: [] };
23274
+ try {
23275
+ await pool.query(JOURNAL_DDL);
23276
+ const journal = await pool.query(`SELECT "id" FROM "auth_migrations"`);
23277
+ const applied = new Set(journal.rows.filter(isJournalRow).map((row) => row.id));
23278
+ const selected = blocks ?? allBlockNames();
23279
+ const flat = selected.flatMap((block) => blockMigrations[block].migrations.map((migration) => ({
23280
+ id: `${block}/${migration.id}`,
23281
+ sql: migration.sql
23282
+ })));
23283
+ await flat.reduce(async (prior, item) => {
23284
+ await prior;
23285
+ return runOne(pool, item.id, item.sql, applied, result, log);
23286
+ }, Promise.resolve());
23287
+ } finally {
23288
+ await pool.end();
23289
+ }
23290
+ return result;
23291
+ };
23292
+
23293
+ // src/migrations/index.ts
23294
+ var initMigration = (block, tables) => ({
23295
+ block,
23296
+ migrations: [{ id: "0001_init", sql: tablesToInitSql(tables) }]
23297
+ });
23298
+ var blockMigrations = {
23299
+ adaptive: initMigration("adaptive", [knownDevicesTable, loginHistoryTable]),
23300
+ apikeys: initMigration("apikeys", [
23301
+ accessTokensTable,
23302
+ apiClientsTable,
23303
+ apiKeysTable
23304
+ ]),
23305
+ audit: initMigration("audit", [auditEventsTable]),
23306
+ credentials: initMigration("credentials", [
23307
+ credentialsTable,
23308
+ credentialResetTokensTable,
23309
+ credentialVerificationTokensTable
23310
+ ]),
23311
+ fga: initMigration("fga", [warrantsTable]),
23312
+ linkedProviders: initMigration("linkedProviders", [
23313
+ linkedProviderBindingsTable,
23314
+ linkedProviderGrantsTable
23315
+ ]),
23316
+ lockout: initMigration("lockout", [lockoutsTable]),
23317
+ mfa: initMigration("mfa", [mfaEnrollmentsTable]),
23318
+ oidc: initMigration("oidc", [
23319
+ oauthClientAssertionJtisTable,
23320
+ oauthClientRegistrationTokensTable,
23321
+ oauthClientsTable,
23322
+ oauthCodesTable,
23323
+ oauthDeviceAuthorizationsTable,
23324
+ oauthInitialAccessTokensTable,
23325
+ oauthLogoutDeliveriesTable,
23326
+ oauthPushedAuthorizationRequestsTable,
23327
+ oauthRefreshTokensTable
23328
+ ]),
23329
+ organizations: initMigration("organizations", [
23330
+ organizationsTable,
23331
+ organizationMembershipsTable,
23332
+ organizationInvitationsTable
23333
+ ]),
23334
+ passwordless: initMigration("passwordless", [passwordlessTokensTable]),
23335
+ portal: initMigration("portal", [setupSessionsTable]),
23336
+ roles: initMigration("roles", [rolesTable]),
23337
+ scim: initMigration("scim", [scimTokensTable]),
23338
+ sessions: initMigration("sessions", [
23339
+ authSessionsTable,
23340
+ authUnregisteredSessionsTable
23341
+ ]),
23342
+ sso: initMigration("sso", [ssoConnectionsTable, samlServiceProvidersTable]),
23343
+ vault: initMigration("vault", [vaultEntriesTable]),
23344
+ webauthn: initMigration("webauthn", [webauthnCredentialsTable]),
23345
+ webhooks: initMigration("webhooks", [webhookDeliveriesTable])
23346
+ };
23347
+ // src/sso/samlIdpRoutes.ts
23348
+ import { Elysia as Elysia35, t as t31 } from "elysia";
23349
+ var HTTP_BAD_REQUEST3 = 400;
23350
+ var HTTP_UNAUTHORIZED3 = 401;
23351
+ var HTTP_FOUND2 = 302;
23352
+ var HTTP_OK3 = 200;
23353
+ var xmlResponse = (body) => new Response(body, {
23354
+ headers: { "content-type": "application/samlmetadata+xml" },
23355
+ status: HTTP_OK3
23356
+ });
23357
+ var htmlResponse = (body) => new Response(body, {
23358
+ headers: { "content-type": "text/html; charset=utf-8" },
23359
+ status: HTTP_OK3
23360
+ });
23361
+ var redirectTo2 = (url) => new Response(null, { headers: { location: url }, status: HTTP_FOUND2 });
23362
+ var errorJson = (status, error) => new Response(JSON.stringify({ error }), {
23363
+ headers: { "content-type": "application/json" },
23364
+ status
23365
+ });
23366
+ var samlIdpRoutes = ({
23367
+ authSessionStore,
23368
+ getNameId,
23369
+ getSamlAttributes,
23370
+ idpAdapter,
23371
+ idpEntityId,
23372
+ loginUrl,
23373
+ samlServiceProviderStore,
23374
+ ssoRoute = DEFAULT_SSO_ROUTE
23375
+ }) => {
23376
+ const ssoIdpRoute = `${ssoRoute}/saml/idp/sso`;
23377
+ const idpInitiateRoute = `${ssoRoute}/saml/idp/sso/initiate`;
23378
+ const idpMetadataRoute = `${ssoRoute}/saml/idp/metadata`;
23379
+ const ssoUrlFor = (requestUrl) => `${new URL(requestUrl).origin}${ssoIdpRoute}`;
23380
+ const renderResponse = async ({
23381
+ acsUrl,
23382
+ inResponseTo,
23383
+ relayState,
23384
+ serviceProviderEntityId,
23385
+ user
23386
+ }) => {
23387
+ const samlResponse = await idpAdapter.createSamlResponse({
23388
+ acsUrl,
23389
+ attributes: getSamlAttributes?.(user),
23390
+ audience: serviceProviderEntityId,
23391
+ idpEntityId,
23392
+ inResponseTo,
23393
+ nameId: getNameId(user),
23394
+ sessionIndex: crypto.randomUUID()
23104
23395
  });
23105
- },
23106
- saveOrganization: async (organization) => {
23107
- const values = {
23108
- created_at_ms: organization.createdAt,
23109
- metadata: organization.metadata ?? null,
23110
- name: organization.name,
23111
- organization_id: organization.organizationId,
23112
- updated_at_ms: organization.updatedAt
23113
- };
23114
- await db.insert(organizationsTable).values(values).onConflictDoUpdate({
23115
- set: values,
23116
- target: organizationsTable.organization_id
23396
+ const html2 = idpAdapter.buildAutoPostForm({
23397
+ acsUrl,
23398
+ relayState,
23399
+ samlResponse
23117
23400
  });
23118
- }
23401
+ return htmlResponse(html2);
23402
+ };
23403
+ const handleSpInitiated = async ({
23404
+ binding,
23405
+ body,
23406
+ inMemorySession,
23407
+ request,
23408
+ userSessionIdValue
23409
+ }) => {
23410
+ if (body.SAMLRequest === undefined) {
23411
+ return errorJson(HTTP_BAD_REQUEST3, "missing_saml_request");
23412
+ }
23413
+ let firstPass;
23414
+ try {
23415
+ firstPass = await idpAdapter.parseAuthnRequest({
23416
+ binding,
23417
+ samlRequest: body.SAMLRequest
23418
+ });
23419
+ } catch {
23420
+ return errorJson(HTTP_BAD_REQUEST3, "invalid_authn_request");
23421
+ }
23422
+ const serviceProvider = await samlServiceProviderStore.findServiceProvider(firstPass.issuer);
23423
+ if (serviceProvider === undefined) {
23424
+ return errorJson(HTTP_BAD_REQUEST3, "unknown_service_provider");
23425
+ }
23426
+ let parsed;
23427
+ try {
23428
+ parsed = await idpAdapter.parseAuthnRequest({
23429
+ binding,
23430
+ samlRequest: body.SAMLRequest,
23431
+ serviceProvider,
23432
+ signature: body.Signature,
23433
+ signatureAlgorithm: body.SigAlg,
23434
+ signedQueryString: binding === "Redirect" ? new URL(request.url).search.slice(1) : undefined
23435
+ });
23436
+ } catch {
23437
+ return errorJson(HTTP_BAD_REQUEST3, "invalid_authn_request");
23438
+ }
23439
+ const userSession = await loadSessionFromSource({
23440
+ authSessionStore,
23441
+ session: inMemorySession,
23442
+ userSessionId: userSessionIdValue
23443
+ });
23444
+ if (userSession === undefined || parsed.forceAuthn === true) {
23445
+ if (loginUrl === undefined) {
23446
+ return errorJson(HTTP_UNAUTHORIZED3, "login_required");
23447
+ }
23448
+ return redirectTo2(`${loginUrl}?return_to=${encodeURIComponent(request.url)}`);
23449
+ }
23450
+ return renderResponse({
23451
+ acsUrl: parsed.acsUrl ?? serviceProvider.acsUrl,
23452
+ inResponseTo: parsed.id,
23453
+ relayState: parsed.relayState ?? body.RelayState,
23454
+ serviceProviderEntityId: serviceProvider.entityId,
23455
+ user: userSession.user
23456
+ });
23457
+ };
23458
+ return new Elysia35().use(sessionStore()).post(ssoIdpRoute, async ({
23459
+ body,
23460
+ cookie: { user_session_id },
23461
+ request,
23462
+ store
23463
+ }) => handleSpInitiated({
23464
+ binding: "POST",
23465
+ body,
23466
+ inMemorySession: store.session,
23467
+ request,
23468
+ userSessionIdValue: user_session_id.value
23469
+ }), {
23470
+ body: t31.Object({
23471
+ RelayState: t31.Optional(t31.String()),
23472
+ SAMLRequest: t31.Optional(t31.String())
23473
+ }),
23474
+ cookie: t31.Cookie({
23475
+ user_session_id: t31.Optional(userSessionIdTypebox)
23476
+ })
23477
+ }).get(ssoIdpRoute, async ({
23478
+ cookie: { user_session_id },
23479
+ query,
23480
+ request,
23481
+ store
23482
+ }) => handleSpInitiated({
23483
+ binding: "Redirect",
23484
+ body: query,
23485
+ inMemorySession: store.session,
23486
+ request,
23487
+ userSessionIdValue: user_session_id.value
23488
+ }), {
23489
+ cookie: t31.Cookie({
23490
+ user_session_id: t31.Optional(userSessionIdTypebox)
23491
+ }),
23492
+ query: t31.Object({
23493
+ RelayState: t31.Optional(t31.String()),
23494
+ SAMLRequest: t31.Optional(t31.String()),
23495
+ SigAlg: t31.Optional(t31.String()),
23496
+ Signature: t31.Optional(t31.String())
23497
+ })
23498
+ }).get(idpInitiateRoute, async ({
23499
+ cookie: { user_session_id },
23500
+ query: { sp: serviceProviderEntityId, RelayState: relayState },
23501
+ request,
23502
+ store
23503
+ }) => {
23504
+ if (serviceProviderEntityId === undefined) {
23505
+ return errorJson(HTTP_BAD_REQUEST3, "missing_sp");
23506
+ }
23507
+ const serviceProvider = await samlServiceProviderStore.findServiceProvider(serviceProviderEntityId);
23508
+ if (serviceProvider === undefined) {
23509
+ return errorJson(HTTP_BAD_REQUEST3, "unknown_service_provider");
23510
+ }
23511
+ const userSession = authSessionStore === undefined ? await loadSessionFromSource({
23512
+ session: store.session,
23513
+ userSessionId: user_session_id.value
23514
+ }) : await loadSessionFromSource({
23515
+ authSessionStore,
23516
+ session: store.session,
23517
+ userSessionId: user_session_id.value
23518
+ });
23519
+ if (userSession === undefined) {
23520
+ if (loginUrl === undefined) {
23521
+ return errorJson(HTTP_UNAUTHORIZED3, "login_required");
23522
+ }
23523
+ return redirectTo2(`${loginUrl}?return_to=${encodeURIComponent(request.url)}`);
23524
+ }
23525
+ return renderResponse({
23526
+ acsUrl: serviceProvider.acsUrl,
23527
+ relayState,
23528
+ serviceProviderEntityId: serviceProvider.entityId,
23529
+ user: userSession.user
23530
+ });
23531
+ }, {
23532
+ cookie: t31.Cookie({
23533
+ user_session_id: t31.Optional(userSessionIdTypebox)
23534
+ }),
23535
+ query: t31.Object({
23536
+ RelayState: t31.Optional(t31.String()),
23537
+ sp: t31.Optional(t31.String())
23538
+ })
23539
+ }).get(idpMetadataRoute, async ({ request }) => xmlResponse(await idpAdapter.getIdpMetadata({
23540
+ entityId: idpEntityId,
23541
+ ssoUrl: ssoUrlFor(request.url)
23542
+ })));
23543
+ };
23544
+ // src/sso/inMemorySamlServiceProviderStore.ts
23545
+ var createInMemorySamlServiceProviderStore = () => {
23546
+ const providers2 = new Map;
23547
+ return {
23548
+ deleteServiceProvider: async (entityId) => {
23549
+ providers2.delete(entityId);
23550
+ },
23551
+ findServiceProvider: async (entityId) => {
23552
+ const found = providers2.get(entityId);
23553
+ return found ? { ...found } : undefined;
23554
+ },
23555
+ listServiceProviders: async () => Array.from(providers2.values()).map((serviceProvider) => ({ ...serviceProvider })),
23556
+ saveServiceProvider: async (serviceProvider) => {
23557
+ providers2.set(serviceProvider.entityId, { ...serviceProvider });
23558
+ }
23559
+ };
23560
+ };
23561
+ // src/sso/inMemorySsoConnectionStore.ts
23562
+ var cloneConnection = (value) => value.type === "oidc" ? {
23563
+ ...value,
23564
+ config: { ...value.config, scopes: [...value.config.scopes] }
23565
+ } : { ...value, config: { ...value.config } };
23566
+ var createInMemorySsoConnectionStore = () => {
23567
+ const connections = new Map;
23568
+ return {
23569
+ deleteConnection: async (connectionId) => {
23570
+ connections.delete(connectionId);
23571
+ },
23572
+ getConnection: async (connectionId) => {
23573
+ const connection = connections.get(connectionId);
23574
+ return connection ? cloneConnection(connection) : undefined;
23575
+ },
23576
+ getConnectionByOrganization: async (organizationId, type) => {
23577
+ const match = Array.from(connections.values()).find((connection) => connection.organizationId === organizationId && connection.enabled && (type === undefined || connection.type === type));
23578
+ return match ? cloneConnection(match) : undefined;
23579
+ },
23580
+ listConnectionsByOrganization: async (organizationId) => Array.from(connections.values()).filter((connection) => connection.organizationId === organizationId).sort((left, right) => right.updatedAt - left.updatedAt).map(cloneConnection),
23581
+ saveConnection: async (connection) => {
23582
+ connections.set(connection.connectionId, cloneConnection(connection));
23583
+ }
23584
+ };
23585
+ };
23586
+ // src/webauthn/inMemoryWebAuthnCredentialStore.ts
23587
+ var cloneCredential2 = (value) => ({
23588
+ ...value,
23589
+ transports: value.transports ? [...value.transports] : undefined
23119
23590
  });
23591
+ var createInMemoryWebAuthnCredentialStore = () => {
23592
+ const credentials = new Map;
23593
+ return {
23594
+ getCredential: async (credentialId) => {
23595
+ const credential = credentials.get(credentialId);
23596
+ return credential ? cloneCredential2(credential) : undefined;
23597
+ },
23598
+ listCredentialsByUser: async (userId) => [...credentials.values()].filter((credential) => credential.userId === userId).map(cloneCredential2),
23599
+ removeCredential: async (credentialId) => {
23600
+ credentials.delete(credentialId);
23601
+ },
23602
+ saveCredential: async (credential) => {
23603
+ credentials.set(credential.credentialId, cloneCredential2(credential));
23604
+ }
23605
+ };
23606
+ };
23607
+ // src/organizations/inMemoryOrganizationStore.ts
23608
+ var membershipKey = (organizationId, userId) => `${organizationId}\x00${userId}`;
23609
+ var cloneMembership = (value) => ({ ...value, roles: [...value.roles] });
23610
+ var cloneInvitation = (value) => ({ ...value, roles: [...value.roles] });
23611
+ var createInMemoryOrganizationStore = () => {
23612
+ const organizations = new Map;
23613
+ const memberships = new Map;
23614
+ const invitations = new Map;
23615
+ return {
23616
+ deleteOrganization: async (organizationId) => {
23617
+ organizations.delete(organizationId);
23618
+ },
23619
+ getInvitation: async (invitationId) => {
23620
+ const invitation = invitations.get(invitationId);
23621
+ return invitation ? cloneInvitation(invitation) : undefined;
23622
+ },
23623
+ getInvitationByTokenHash: async (tokenHash) => {
23624
+ const invitation = [...invitations.values()].find((entry) => entry.tokenHash === tokenHash);
23625
+ return invitation ? cloneInvitation(invitation) : undefined;
23626
+ },
23627
+ getMembership: async (organizationId, userId) => {
23628
+ const membership = memberships.get(membershipKey(organizationId, userId));
23629
+ return membership ? cloneMembership(membership) : undefined;
23630
+ },
23631
+ getOrganization: async (organizationId) => {
23632
+ const organization = organizations.get(organizationId);
23633
+ return organization ? { ...organization } : undefined;
23634
+ },
23635
+ listInvitationsByOrganization: async (organizationId) => [...invitations.values()].filter((entry) => entry.organizationId === organizationId).map(cloneInvitation),
23636
+ listMembershipsByOrganization: async (organizationId) => [...memberships.values()].filter((entry) => entry.organizationId === organizationId).map(cloneMembership),
23637
+ listMembershipsByUser: async (userId) => [...memberships.values()].filter((entry) => entry.userId === userId).map(cloneMembership),
23638
+ removeMembership: async (organizationId, userId) => {
23639
+ memberships.delete(membershipKey(organizationId, userId));
23640
+ },
23641
+ saveInvitation: async (invitation) => {
23642
+ invitations.set(invitation.invitationId, cloneInvitation(invitation));
23643
+ },
23644
+ saveMembership: async (membership) => {
23645
+ memberships.set(membershipKey(membership.organizationId, membership.userId), cloneMembership(membership));
23646
+ },
23647
+ saveOrganization: async (organization) => {
23648
+ organizations.set(organization.organizationId, {
23649
+ ...organization
23650
+ });
23651
+ }
23652
+ };
23653
+ };
23120
23654
  // src/roles/resolver.ts
23121
23655
  var WILDCARD = "*";
23122
23656
  var createMembershipPermissionResolver = ({
@@ -23174,51 +23708,6 @@ var createInMemoryRoleStore = () => {
23174
23708
  }
23175
23709
  };
23176
23710
  };
23177
- // src/roles/postgresRoleStore.ts
23178
- var ID_LENGTH14 = 255;
23179
- var SLUG_LENGTH = 128;
23180
- var GLOBAL_SCOPE = "";
23181
- var rolesTable = pgTable("auth_roles", {
23182
- created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
23183
- organization_id: varchar("organization_id", { length: ID_LENGTH14 }).notNull().default(GLOBAL_SCOPE),
23184
- permissions: jsonb("permissions").$type().notNull().default([]),
23185
- slug: varchar("slug", { length: SLUG_LENGTH }).notNull(),
23186
- updated_at_ms: bigint("updated_at_ms", { mode: "number" }).notNull()
23187
- }, (table) => [primaryKey({ columns: [table.organization_id, table.slug] })]);
23188
- var toRole = (row) => ({
23189
- createdAt: row.created_at_ms,
23190
- organizationId: row.organization_id === GLOBAL_SCOPE ? undefined : row.organization_id,
23191
- permissions: row.permissions,
23192
- slug: row.slug,
23193
- updatedAt: row.updated_at_ms
23194
- });
23195
- var createNeonRoleStore = (databaseUrl) => createPostgresRoleStore(createNeonDatabase(databaseUrl));
23196
- var createPostgresRoleStore = (db) => ({
23197
- deleteRole: async (slug, organizationId) => {
23198
- await db.delete(rolesTable).where(and(eq(rolesTable.organization_id, organizationId ?? GLOBAL_SCOPE), eq(rolesTable.slug, slug)));
23199
- },
23200
- getRole: async (slug, organizationId) => {
23201
- const [row] = await db.select().from(rolesTable).where(and(eq(rolesTable.organization_id, organizationId ?? GLOBAL_SCOPE), eq(rolesTable.slug, slug))).limit(1);
23202
- return row ? toRole(row) : undefined;
23203
- },
23204
- listRoles: async (organizationId) => {
23205
- const rows = await db.select().from(rolesTable).where(eq(rolesTable.organization_id, organizationId ?? GLOBAL_SCOPE));
23206
- return rows.map(toRole);
23207
- },
23208
- saveRole: async (role) => {
23209
- const values = {
23210
- created_at_ms: role.createdAt,
23211
- organization_id: role.organizationId ?? GLOBAL_SCOPE,
23212
- permissions: role.permissions,
23213
- slug: role.slug,
23214
- updated_at_ms: role.updatedAt
23215
- };
23216
- await db.insert(rolesTable).values(values).onConflictDoUpdate({
23217
- set: values,
23218
- target: [rolesTable.organization_id, rolesTable.slug]
23219
- });
23220
- }
23221
- });
23222
23711
  // src/passwordless/inMemoryPasswordlessTokenStore.ts
23223
23712
  var createInMemoryPasswordlessTokenStore = () => {
23224
23713
  const tokens = new Map;
@@ -23234,42 +23723,12 @@ var createInMemoryPasswordlessTokenStore = () => {
23234
23723
  }
23235
23724
  };
23236
23725
  };
23237
- // src/passwordless/postgresPasswordlessTokenStore.ts
23238
- var ID_LENGTH15 = 255;
23239
- var passwordlessTokensTable = pgTable("auth_passwordless_tokens", {
23240
- email: varchar("email", { length: ID_LENGTH15 }).notNull(),
23241
- expires_at_ms: bigint("expires_at_ms", { mode: "number" }).notNull(),
23242
- token_hash: varchar("token_hash", { length: ID_LENGTH15 }).primaryKey()
23243
- });
23244
- var toToken3 = (row) => ({
23245
- email: row.email,
23246
- expiresAt: row.expires_at_ms,
23247
- tokenHash: row.token_hash
23248
- });
23249
- var createNeonPasswordlessTokenStore = (databaseUrl) => createPostgresPasswordlessTokenStore(createNeonDatabase(databaseUrl));
23250
- var createPostgresPasswordlessTokenStore = (db) => ({
23251
- consumeToken: async (tokenHash) => {
23252
- const [row] = await db.delete(passwordlessTokensTable).where(eq(passwordlessTokensTable.token_hash, tokenHash)).returning();
23253
- return row ? toToken3(row) : undefined;
23254
- },
23255
- saveToken: async (token) => {
23256
- const values = {
23257
- email: token.email,
23258
- expires_at_ms: token.expiresAt,
23259
- token_hash: token.tokenHash
23260
- };
23261
- await db.insert(passwordlessTokensTable).values(values).onConflictDoUpdate({
23262
- set: values,
23263
- target: passwordlessTokensTable.token_hash
23264
- });
23265
- }
23266
- });
23267
23726
  // src/webhooks/inMemoryStore.ts
23268
- var DEFAULT_LIST_LIMIT3 = 100;
23727
+ var DEFAULT_LIST_LIMIT4 = 100;
23269
23728
  var createInMemoryWebhookDeliveryStore = () => {
23270
23729
  const failures = new Map;
23271
23730
  return {
23272
- listFailed: async (limit = DEFAULT_LIST_LIMIT3) => Array.from(failures.values()).sort((left, right) => right.createdAt - left.createdAt).slice(0, limit),
23731
+ listFailed: async (limit = DEFAULT_LIST_LIMIT4) => Array.from(failures.values()).sort((left, right) => right.createdAt - left.createdAt).slice(0, limit),
23273
23732
  recordFailure: async (delivery) => {
23274
23733
  failures.set(delivery.envelope.id, delivery);
23275
23734
  },
@@ -23278,48 +23737,6 @@ var createInMemoryWebhookDeliveryStore = () => {
23278
23737
  }
23279
23738
  };
23280
23739
  };
23281
- // src/webhooks/postgresStore.ts
23282
- var ID_LENGTH16 = 255;
23283
- var URL_LENGTH3 = 2048;
23284
- var DEFAULT_LIST_LIMIT4 = 100;
23285
- var webhookDeliveriesTable = pgTable("auth_webhook_deliveries", {
23286
- attempts: bigint("attempts", { mode: "number" }).notNull(),
23287
- created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
23288
- endpoint_url: varchar("endpoint_url", { length: URL_LENGTH3 }).notNull(),
23289
- envelope_id: varchar("envelope_id", { length: ID_LENGTH16 }).primaryKey(),
23290
- envelope_json: jsonb("envelope_json").$type().notNull(),
23291
- last_error: text("last_error"),
23292
- last_status: bigint("last_status", { mode: "number" })
23293
- });
23294
- var toDelivery = (row) => ({
23295
- attempts: row.attempts,
23296
- createdAt: row.created_at_ms,
23297
- endpointUrl: row.endpoint_url,
23298
- envelope: row.envelope_json,
23299
- lastError: row.last_error ?? undefined,
23300
- lastStatus: row.last_status ?? undefined
23301
- });
23302
- var createNeonWebhookDeliveryStore = (databaseUrl) => createPostgresWebhookDeliveryStore(createNeonDatabase(databaseUrl));
23303
- var createPostgresWebhookDeliveryStore = (db) => ({
23304
- listFailed: async (limit = DEFAULT_LIST_LIMIT4) => {
23305
- const rows = await db.select().from(webhookDeliveriesTable).orderBy(desc(webhookDeliveriesTable.created_at_ms)).limit(limit);
23306
- return rows.map(toDelivery);
23307
- },
23308
- recordFailure: async (delivery) => {
23309
- await db.insert(webhookDeliveriesTable).values({
23310
- attempts: delivery.attempts,
23311
- created_at_ms: delivery.createdAt,
23312
- endpoint_url: delivery.endpointUrl,
23313
- envelope_id: delivery.envelope.id,
23314
- envelope_json: delivery.envelope,
23315
- last_error: delivery.lastError ?? null,
23316
- last_status: delivery.lastStatus ?? null
23317
- });
23318
- },
23319
- removeFailure: async (envelopeId) => {
23320
- await db.delete(webhookDeliveriesTable).where(eq(webhookDeliveriesTable.envelope_id, envelopeId));
23321
- }
23322
- });
23323
23740
  // src/portal/inMemorySetupSessionStore.ts
23324
23741
  var cloneSession = (value) => ({
23325
23742
  ...value,
@@ -23340,55 +23757,6 @@ var createInMemorySetupSessionStore = () => {
23340
23757
  }
23341
23758
  };
23342
23759
  };
23343
- // src/portal/postgresSetupSessionStore.ts
23344
- var ID_LENGTH17 = 255;
23345
- var setupSessionsTable = pgTable("auth_setup_sessions", {
23346
- capabilities: jsonb("capabilities").$type().notNull().default([]),
23347
- created_at_ms: bigint("created_at_ms", { mode: "number" }).notNull(),
23348
- created_by: varchar("created_by", { length: ID_LENGTH17 }),
23349
- expires_at_ms: bigint("expires_at_ms", { mode: "number" }).notNull(),
23350
- organization_id: varchar("organization_id", {
23351
- length: ID_LENGTH17
23352
- }).notNull(),
23353
- setup_session_id: varchar("setup_session_id", {
23354
- length: ID_LENGTH17
23355
- }).primaryKey(),
23356
- token_hash: varchar("token_hash", { length: ID_LENGTH17 }).notNull().unique()
23357
- });
23358
- var toSession = (row) => ({
23359
- capabilities: row.capabilities,
23360
- createdAt: row.created_at_ms,
23361
- createdBy: row.created_by ?? undefined,
23362
- expiresAt: row.expires_at_ms,
23363
- organizationId: row.organization_id,
23364
- setupSessionId: row.setup_session_id,
23365
- tokenHash: row.token_hash
23366
- });
23367
- var createNeonSetupSessionStore = (databaseUrl) => createPostgresSetupSessionStore(createNeonDatabase(databaseUrl));
23368
- var createPostgresSetupSessionStore = (db) => ({
23369
- deleteSetupSession: async (setupSessionId) => {
23370
- await db.delete(setupSessionsTable).where(eq(setupSessionsTable.setup_session_id, setupSessionId));
23371
- },
23372
- getSetupSessionByTokenHash: async (tokenHash) => {
23373
- const [row] = await db.select().from(setupSessionsTable).where(eq(setupSessionsTable.token_hash, tokenHash)).limit(1);
23374
- return row ? toSession(row) : undefined;
23375
- },
23376
- saveSetupSession: async (session) => {
23377
- const values = {
23378
- capabilities: session.capabilities,
23379
- created_at_ms: session.createdAt,
23380
- created_by: session.createdBy ?? null,
23381
- expires_at_ms: session.expiresAt,
23382
- organization_id: session.organizationId,
23383
- setup_session_id: session.setupSessionId,
23384
- token_hash: session.tokenHash
23385
- };
23386
- await db.insert(setupSessionsTable).values(values).onConflictDoUpdate({
23387
- set: values,
23388
- target: setupSessionsTable.setup_session_id
23389
- });
23390
- }
23391
- });
23392
23760
 
23393
23761
  // src/index.ts
23394
23762
  var auth = async ({
@@ -23423,6 +23791,7 @@ var auth = async ({
23423
23791
  webauthn,
23424
23792
  webhooks,
23425
23793
  htmx,
23794
+ tracing,
23426
23795
  resolveAuthIntent,
23427
23796
  onAuthorizeSuccess,
23428
23797
  onAuthorizeError,
@@ -23441,6 +23810,8 @@ var auth = async ({
23441
23810
  onRevocationError,
23442
23811
  onSessionCleanup
23443
23812
  }) => {
23813
+ if (tracing !== undefined)
23814
+ await initTracing(tracing);
23444
23815
  const clientProviders = await buildClientProviders(providersConfiguration, createOAuth2Client);
23445
23816
  const resolvedCookieSecure = resolveCookieSecure(cookieSecure);
23446
23817
  const webhookDispatch = webhooks ? createWebhookDispatcher(webhooks) : undefined;
@@ -23559,6 +23930,7 @@ var auth = async ({
23559
23930
  };
23560
23931
  export {
23561
23932
  writeWarrant,
23933
+ withSpan,
23562
23934
  webhookDeliveriesTable,
23563
23935
  webauthnRoutes,
23564
23936
  webauthnCredentialsTable,
@@ -23609,6 +23981,7 @@ export {
23609
23981
  samlSsoRoutes,
23610
23982
  samlServiceProvidersTable,
23611
23983
  samlIdpRoutes,
23984
+ runMigrations,
23612
23985
  rotateVaultKey,
23613
23986
  rotateMfaEncryptionKey,
23614
23987
  rolesTable,
@@ -23698,6 +24071,7 @@ export {
23698
24071
  inviteToOrganization,
23699
24072
  introspectToken,
23700
24073
  instantiateUserSession,
24074
+ initTracing,
23701
24075
  importUsers,
23702
24076
  importUser,
23703
24077
  hashToken,
@@ -23875,6 +24249,7 @@ export {
23875
24249
  complianceRoutes,
23876
24250
  check,
23877
24251
  buildClientProviders,
24252
+ blockMigrations,
23878
24253
  base32Encode,
23879
24254
  base32Decode,
23880
24255
  authProviderOption,
@@ -23925,5 +24300,5 @@ export {
23925
24300
  AuthIdentityConflictError
23926
24301
  };
23927
24302
 
23928
- //# debugId=0F54EE0288E37B6464756E2164756E21
24303
+ //# debugId=E33462A0DBAD894164756E2164756E21
23929
24304
  //# sourceMappingURL=index.js.map