@absolutejs/auth 0.62.0 → 0.64.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.
@@ -0,0 +1,43 @@
1
+ import { Elysia } from 'elysia';
2
+ import type { AuthSessionSource } from '../session/types';
3
+ export declare const requireAuthPlugin: <UserType>({ authSessionStore }?: {
4
+ authSessionStore?: AuthSessionSource<UserType>;
5
+ }) => Elysia<"", {
6
+ decorator: {};
7
+ store: {
8
+ session: import("..").SessionRecord<UserType>;
9
+ unregisteredSession: import("..").UnregisteredSessionRecord;
10
+ };
11
+ derive: {};
12
+ resolve: {
13
+ readonly user: NonNullable<UserType> | null;
14
+ };
15
+ }, {
16
+ typebox: {};
17
+ error: {};
18
+ }, {
19
+ schema: import("elysia").UnwrapRoute<{
20
+ cookie: import("@sinclair/typebox").TObject<{
21
+ user_session_id: import("@sinclair/typebox").TOptional<import("@sinclair/typebox").TTemplateLiteralSyntax<"${string}-${string}-${string}-${string}-${string}">>;
22
+ }>;
23
+ }, {}, "">;
24
+ standaloneSchema: {};
25
+ macro: {};
26
+ macroFn: {};
27
+ parser: {};
28
+ response: {
29
+ 401: "User is not authenticated";
30
+ };
31
+ }, {}, {
32
+ derive: {};
33
+ resolve: {};
34
+ schema: {};
35
+ standaloneSchema: {};
36
+ response: {};
37
+ }, {
38
+ derive: {};
39
+ resolve: {};
40
+ schema: {};
41
+ standaloneSchema: {};
42
+ response: {};
43
+ }>;
package/dist/server.d.ts CHANGED
@@ -14,6 +14,7 @@ export type { SetupCapability, SetupSession, SetupSessionStore } from './portal/
14
14
  export { createSetupSession } from './portal/operations';
15
15
  export { createPostgresSetupSessionStore } from './portal/postgresSetupSessionStore';
16
16
  export { protectRoutePlugin } from './routes/protectRoute';
17
+ export { requireAuthPlugin } from './routes/requireAuth';
17
18
  export type { ScimConfig } from './scim/config';
18
19
  export type { ScimFilter, ScimGroup, ScimGroupInput, ScimTokenStore, ScimUser, ScimUserInput } from './scim/types';
19
20
  export { createPostgresScimTokenStore } from './scim/postgresScimTokenStore';
package/dist/server.js CHANGED
@@ -3978,7 +3978,7 @@ var createCustomOAuth2Client = (providerConfig, credentials) => buildOAuth2Clien
3978
3978
  var createOAuth2Client = (providerName, config) => buildOAuth2Client(providers[providerName], config);
3979
3979
 
3980
3980
  // src/index.ts
3981
- import { Elysia as Elysia45 } from "elysia";
3981
+ import { Elysia as Elysia46 } from "elysia";
3982
3982
 
3983
3983
  // src/apikeys/routes.ts
3984
3984
  import { Elysia, t } from "elysia";
@@ -6149,6 +6149,20 @@ var isTrustedOrigin = (request, trustedOrigins) => {
6149
6149
  const origin = request.headers.get("origin");
6150
6150
  return origin !== null && trustedOrigins.includes(origin);
6151
6151
  };
6152
+ var resolveOriginAllowed = async ({
6153
+ enforce = true,
6154
+ onUntrustedOrigin,
6155
+ request,
6156
+ trustedOrigins
6157
+ }) => {
6158
+ if (isTrustedOrigin(request, trustedOrigins))
6159
+ return true;
6160
+ await onUntrustedOrigin?.({
6161
+ origin: request.headers.get("origin"),
6162
+ request
6163
+ });
6164
+ return enforce === false;
6165
+ };
6152
6166
 
6153
6167
  // src/credentials/import.ts
6154
6168
  init_crypto();
@@ -6345,12 +6359,14 @@ var credentialsLogin = ({
6345
6359
  checkBreachesOnLogin,
6346
6360
  cookieSecure,
6347
6361
  credentialStore,
6362
+ enforceTrustedOrigins,
6348
6363
  getUserByEmail,
6349
6364
  isMfaRequired,
6350
6365
  lockoutGuard,
6351
6366
  loginRoute = "/auth/login",
6352
6367
  onCredentialsLoginError,
6353
6368
  onCredentialsLoginSuccess,
6369
+ onUntrustedOrigin,
6354
6370
  passwordVerifier,
6355
6371
  rehashOnLogin = false,
6356
6372
  requireEmailVerification = false,
@@ -6363,7 +6379,12 @@ var credentialsLogin = ({
6363
6379
  status,
6364
6380
  store: { session, unregisteredSession }
6365
6381
  }) => withSpan("auth.credentials.login", undefined, async (span) => {
6366
- if (!isTrustedOrigin(request, trustedOrigins)) {
6382
+ if (!await resolveOriginAllowed({
6383
+ enforce: enforceTrustedOrigins,
6384
+ onUntrustedOrigin,
6385
+ request,
6386
+ trustedOrigins
6387
+ })) {
6367
6388
  return status("Forbidden", "Request origin is not allowed");
6368
6389
  }
6369
6390
  const headerBag = {};
@@ -6521,11 +6542,13 @@ var credentialsRegister = ({
6521
6542
  authSessionStore,
6522
6543
  cookieSecure,
6523
6544
  credentialStore,
6545
+ enforceTrustedOrigins,
6524
6546
  onCreateCredentialUser,
6525
6547
  onCredentialsLoginSuccess,
6526
6548
  onExistingAccount,
6527
6549
  onRegistrationSuccess,
6528
6550
  onSendEmail,
6551
+ onUntrustedOrigin,
6529
6552
  passwordPolicy,
6530
6553
  registerRoute = "/auth/register",
6531
6554
  requireEmailVerification = false,
@@ -6540,7 +6563,12 @@ var credentialsRegister = ({
6540
6563
  status,
6541
6564
  store: { session }
6542
6565
  }) => withSpan("auth.credentials.register", undefined, async () => {
6543
- if (!isTrustedOrigin(request, trustedOrigins)) {
6566
+ if (!await resolveOriginAllowed({
6567
+ enforce: enforceTrustedOrigins,
6568
+ onUntrustedOrigin,
6569
+ request,
6570
+ trustedOrigins
6571
+ })) {
6544
6572
  return status("Forbidden", "Request origin is not allowed");
6545
6573
  }
6546
6574
  const normalizedEmail = email.trim().toLowerCase();
@@ -32528,6 +32556,21 @@ var createInMemoryLinkedProviderStores = (input = {}) => {
32528
32556
  };
32529
32557
  return { bindingStore, grantStore };
32530
32558
  };
32559
+ // src/routes/requireAuth.ts
32560
+ import { Elysia as Elysia41, t as t33 } from "elysia";
32561
+ var requireAuthPlugin = ({
32562
+ authSessionStore
32563
+ } = {}) => new Elysia41({
32564
+ name: "@absolutejs/auth/require-auth",
32565
+ seed: pluginDependencySeed(authSessionStore)
32566
+ }).use(sessionStore()).guard({ cookie: t33.Cookie({ user_session_id: userSessionIdTypebox }) }).resolve(async ({ store: { session }, cookie: { user_session_id } }) => {
32567
+ const { user } = await getStatusFromSource({
32568
+ authSessionStore,
32569
+ session,
32570
+ user_session_id
32571
+ });
32572
+ return { user: user ?? null };
32573
+ }).onBeforeHandle(({ user, status }) => user === null ? status("Unauthorized", "User is not authenticated") : undefined).as("global");
32531
32574
  // src/session/impersonation.ts
32532
32575
  init_constants();
32533
32576
  var DEFAULT_IMPERSONATION_TTL_MS = MILLISECONDS_IN_AN_HOUR;
@@ -33946,7 +33989,7 @@ var createInMemoryCredentialOfferStore = () => {
33946
33989
  };
33947
33990
  };
33948
33991
  // src/oidc/vciRoutes.ts
33949
- import { Elysia as Elysia41, t as t33 } from "elysia";
33992
+ import { Elysia as Elysia42, t as t34 } from "elysia";
33950
33993
  var HTTP_OK4 = 200;
33951
33994
  var HTTP_BAD_REQUEST4 = 400;
33952
33995
  var HTTP_UNAUTHORIZED5 = 401;
@@ -33971,7 +34014,7 @@ var vciRoutes = ({
33971
34014
  const credentialRoute = `${vciRoute}/credential`;
33972
34015
  const nonceRoute = `${vciRoute}/nonce`;
33973
34016
  const vciSigningKey = vciConfig.signingKey ?? signingKey;
33974
- return new Elysia41().get("/.well-known/openid-credential-issuer", () => Response.json(buildIssuerMetadata({
34017
+ return new Elysia42().get("/.well-known/openid-credential-issuer", () => Response.json(buildIssuerMetadata({
33975
34018
  config: vciConfig,
33976
34019
  issuer: issuerUrl,
33977
34020
  vciRoute
@@ -33994,11 +34037,11 @@ var vciRoutes = ({
33994
34037
  return errorBody(result.error, HTTP_BAD_REQUEST4);
33995
34038
  return Response.json({ credential: result.credential, format: result.format }, { status: HTTP_OK4 });
33996
34039
  }, {
33997
- body: t33.Object({
33998
- format: t33.Optional(t33.Union([t33.Literal("vc+sd-jwt")])),
33999
- proof: t33.Optional(t33.Object({
34000
- jwt: t33.String(),
34001
- proof_type: t33.Literal("jwt")
34040
+ body: t34.Object({
34041
+ format: t34.Optional(t34.Union([t34.Literal("vc+sd-jwt")])),
34042
+ proof: t34.Optional(t34.Object({
34043
+ jwt: t34.String(),
34044
+ proof_type: t34.Literal("jwt")
34002
34045
  }))
34003
34046
  })
34004
34047
  }).post(nonceRoute, async () => {
@@ -34120,7 +34163,7 @@ var verifyStatusListJwt = async ({
34120
34163
  };
34121
34164
  };
34122
34165
  // src/vc/statusListRoutes.ts
34123
- import { Elysia as Elysia42, t as t34 } from "elysia";
34166
+ import { Elysia as Elysia43, t as t35 } from "elysia";
34124
34167
  var HTTP_OK5 = 200;
34125
34168
  var HTTP_NOT_FOUND = 404;
34126
34169
  var DEFAULT_STATUS_ROUTE = "/vc/status";
@@ -34132,7 +34175,7 @@ var statusListRoutes = ({
34132
34175
  ttlSeconds
34133
34176
  }) => {
34134
34177
  const listRoute = `${statusRoute}/:listId`;
34135
- return new Elysia42().get(listRoute, async ({ params: { listId } }) => {
34178
+ return new Elysia43().get(listRoute, async ({ params: { listId } }) => {
34136
34179
  const bits = await getStatusList(listId);
34137
34180
  if (bits === undefined) {
34138
34181
  return new Response("Not found", { status: HTTP_NOT_FOUND });
@@ -34148,7 +34191,7 @@ var statusListRoutes = ({
34148
34191
  headers: { "content-type": STATUS_LIST_SUB_TYP },
34149
34192
  status: HTTP_OK5
34150
34193
  });
34151
- }, { params: t34.Object({ listId: t34.String() }) });
34194
+ }, { params: t35.Object({ listId: t35.String() }) });
34152
34195
  };
34153
34196
  // src/vc/openid4vp.ts
34154
34197
  init_crypto();
@@ -34353,7 +34396,7 @@ var createInMemoryPresentationRequestStore = () => {
34353
34396
  };
34354
34397
  };
34355
34398
  // src/vc/vpRoutes.ts
34356
- import { Elysia as Elysia43, t as t35 } from "elysia";
34399
+ import { Elysia as Elysia44, t as t36 } from "elysia";
34357
34400
  var HTTP_OK6 = 200;
34358
34401
  var HTTP_BAD_REQUEST5 = 400;
34359
34402
  var HTTP_NOT_FOUND2 = 404;
@@ -34372,7 +34415,7 @@ var vpRoutes = ({
34372
34415
  const authorizeRoute = `${vpRoute}/authorize`;
34373
34416
  const requestRoute = `${vpRoute}/request/:id`;
34374
34417
  const responseRoute = `${vpRoute}/response`;
34375
- return new Elysia43().post(authorizeRoute, async ({ body }) => {
34418
+ return new Elysia44().post(authorizeRoute, async ({ body }) => {
34376
34419
  const input = {
34377
34420
  clientId: body.client_id ?? defaultClientId,
34378
34421
  requestedClaims: body.requested_claims,
@@ -34390,10 +34433,10 @@ var vpRoutes = ({
34390
34433
  requestId: result.request.requestId
34391
34434
  }, { status: HTTP_OK6 });
34392
34435
  }, {
34393
- body: t35.Object({
34394
- client_id: t35.Optional(t35.String()),
34395
- requested_claims: t35.Array(t35.String()),
34396
- state: t35.Optional(t35.String())
34436
+ body: t36.Object({
34437
+ client_id: t36.Optional(t36.String()),
34438
+ requested_claims: t36.Array(t36.String()),
34439
+ state: t36.Optional(t36.String())
34397
34440
  })
34398
34441
  }).get(requestRoute, async ({ params: { id } }) => {
34399
34442
  const stored = await vpConfig.requestStore.getRequest(id);
@@ -34419,7 +34462,7 @@ var vpRoutes = ({
34419
34462
  },
34420
34463
  status: HTTP_OK6
34421
34464
  });
34422
- }, { params: t35.Object({ id: t35.String() }) }).post(responseRoute, async ({ body }) => {
34465
+ }, { params: t36.Object({ id: t36.String() }) }).post(responseRoute, async ({ body }) => {
34423
34466
  const requestId = body.state;
34424
34467
  if (requestId === undefined) {
34425
34468
  return errorBody2("missing_state", HTTP_BAD_REQUEST5);
@@ -34440,10 +34483,10 @@ var vpRoutes = ({
34440
34483
  verified: true
34441
34484
  }, { status: HTTP_OK6 });
34442
34485
  }, {
34443
- body: t35.Object({
34444
- presentation_submission: t35.Optional(t35.Unknown()),
34445
- state: t35.Optional(t35.String()),
34446
- vp_token: t35.String()
34486
+ body: t36.Object({
34487
+ presentation_submission: t36.Optional(t36.Unknown()),
34488
+ state: t36.Optional(t36.String()),
34489
+ vp_token: t36.String()
34447
34490
  })
34448
34491
  });
34449
34492
  };
@@ -37799,7 +37842,7 @@ var blockMigrations = {
37799
37842
  webhooks: initMigration("webhooks", [webhookDeliveriesTable])
37800
37843
  };
37801
37844
  // src/sso/samlIdpRoutes.ts
37802
- import { Elysia as Elysia44, t as t36 } from "elysia";
37845
+ import { Elysia as Elysia45, t as t37 } from "elysia";
37803
37846
  var HTTP_BAD_REQUEST6 = 400;
37804
37847
  var HTTP_UNAUTHORIZED6 = 401;
37805
37848
  var HTTP_FOUND2 = 302;
@@ -37909,19 +37952,19 @@ var samlIdpRoutes = ({
37909
37952
  user: userSession.user
37910
37953
  });
37911
37954
  };
37912
- return new Elysia44().use(sessionStore()).post(ssoIdpRoute, async ({ body, cookie: { user_session_id }, request, store }) => handleSpInitiated({
37955
+ return new Elysia45().use(sessionStore()).post(ssoIdpRoute, async ({ body, cookie: { user_session_id }, request, store }) => handleSpInitiated({
37913
37956
  binding: "POST",
37914
37957
  body,
37915
37958
  inMemorySession: store.session,
37916
37959
  request,
37917
37960
  userSessionIdValue: user_session_id.value
37918
37961
  }), {
37919
- body: t36.Object({
37920
- RelayState: t36.Optional(t36.String()),
37921
- SAMLRequest: t36.Optional(t36.String())
37962
+ body: t37.Object({
37963
+ RelayState: t37.Optional(t37.String()),
37964
+ SAMLRequest: t37.Optional(t37.String())
37922
37965
  }),
37923
- cookie: t36.Cookie({
37924
- user_session_id: t36.Optional(userSessionIdTypebox)
37966
+ cookie: t37.Cookie({
37967
+ user_session_id: t37.Optional(userSessionIdTypebox)
37925
37968
  })
37926
37969
  }).get(ssoIdpRoute, async ({ cookie: { user_session_id }, query, request, store }) => handleSpInitiated({
37927
37970
  binding: "Redirect",
@@ -37930,14 +37973,14 @@ var samlIdpRoutes = ({
37930
37973
  request,
37931
37974
  userSessionIdValue: user_session_id.value
37932
37975
  }), {
37933
- cookie: t36.Cookie({
37934
- user_session_id: t36.Optional(userSessionIdTypebox)
37976
+ cookie: t37.Cookie({
37977
+ user_session_id: t37.Optional(userSessionIdTypebox)
37935
37978
  }),
37936
- query: t36.Object({
37937
- RelayState: t36.Optional(t36.String()),
37938
- SAMLRequest: t36.Optional(t36.String()),
37939
- SigAlg: t36.Optional(t36.String()),
37940
- Signature: t36.Optional(t36.String())
37979
+ query: t37.Object({
37980
+ RelayState: t37.Optional(t37.String()),
37981
+ SAMLRequest: t37.Optional(t37.String()),
37982
+ SigAlg: t37.Optional(t37.String()),
37983
+ Signature: t37.Optional(t37.String())
37941
37984
  })
37942
37985
  }).get(idpInitiateRoute, async ({
37943
37986
  cookie: { user_session_id },
@@ -37973,12 +38016,12 @@ var samlIdpRoutes = ({
37973
38016
  user: userSession.user
37974
38017
  });
37975
38018
  }, {
37976
- cookie: t36.Cookie({
37977
- user_session_id: t36.Optional(userSessionIdTypebox)
38019
+ cookie: t37.Cookie({
38020
+ user_session_id: t37.Optional(userSessionIdTypebox)
37978
38021
  }),
37979
- query: t36.Object({
37980
- RelayState: t36.Optional(t36.String()),
37981
- sp: t36.Optional(t36.String())
38022
+ query: t37.Object({
38023
+ RelayState: t37.Optional(t37.String()),
38024
+ sp: t37.Optional(t37.String())
37982
38025
  })
37983
38026
  }).get(idpMetadataRoute, async ({ request }) => xmlResponse(await idpAdapter.getIdpMetadata({
37984
38027
  entityId: idpEntityId,
@@ -38427,7 +38470,7 @@ var buildAuthApplications = async (configuration) => {
38427
38470
  const auditedOnRevocationSuccess = auditEmit ? composeRevocationAudit(onRevocationSuccess, auditEmit) : onRevocationSuccess;
38428
38471
  const auditedOnSignOut = auditEmit ? composeSignOutAudit(onSignOut, auditEmit) : onSignOut;
38429
38472
  const pluginSeed = pluginDependencySeed(configuration);
38430
- const coreRoutes = new Elysia45({
38473
+ const coreRoutes = new Elysia46({
38431
38474
  name: "@absolutejs/auth/core-routes",
38432
38475
  seed: pluginSeed
38433
38476
  }).use([
@@ -38484,7 +38527,7 @@ var buildAuthApplications = async (configuration) => {
38484
38527
  profileRoute
38485
38528
  })
38486
38529
  ]);
38487
- const featureRoutes = new Elysia45({
38530
+ const featureRoutes = new Elysia46({
38488
38531
  name: "@absolutejs/auth/feature-routes",
38489
38532
  seed: pluginSeed
38490
38533
  }).use([
@@ -38493,64 +38536,64 @@ var buildAuthApplications = async (configuration) => {
38493
38536
  authSessionStore,
38494
38537
  cookieSecure: resolvedCookieSecure,
38495
38538
  lockoutGuard
38496
- }) : new Elysia45,
38539
+ }) : new Elysia46,
38497
38540
  auditedMfa ? mfaRoutes({
38498
38541
  ...auditedMfa,
38499
38542
  authSessionStore,
38500
38543
  cookieSecure: resolvedCookieSecure,
38501
38544
  verificationProvider
38502
- }) : new Elysia45,
38545
+ }) : new Elysia46,
38503
38546
  passwordless ? passwordlessRoutes({
38504
38547
  ...passwordless,
38505
38548
  authSessionStore,
38506
38549
  cookieSecure: resolvedCookieSecure,
38507
38550
  emit: auditEmit
38508
- }) : new Elysia45,
38509
- sessions ? sessionRoutes({ ...sessions, authSessionStore }) : new Elysia45,
38551
+ }) : new Elysia46,
38552
+ sessions ? sessionRoutes({ ...sessions, authSessionStore }) : new Elysia46,
38510
38553
  sso ? oidcSsoRoutes({
38511
38554
  ...sso,
38512
38555
  authSessionStore,
38513
38556
  cookieSecure: resolvedCookieSecure
38514
- }) : new Elysia45,
38557
+ }) : new Elysia46,
38515
38558
  sso && sso.samlAdapter ? samlSsoRoutes({
38516
38559
  ...sso,
38517
38560
  authSessionStore,
38518
38561
  cookieSecure: resolvedCookieSecure,
38519
38562
  samlAdapter: sso.samlAdapter
38520
- }) : new Elysia45,
38563
+ }) : new Elysia46,
38521
38564
  sso && sso.getOrganizationByEmailDomain ? ssoDiscoveryRoute({
38522
38565
  getOrganizationByEmailDomain: sso.getOrganizationByEmailDomain,
38523
38566
  ssoConnectionStore: sso.ssoConnectionStore,
38524
38567
  ssoRoute: sso.ssoRoute
38525
- }) : new Elysia45,
38526
- scim ? scimRoutes(scim) : new Elysia45,
38527
- apikeys ? apiKeysRoutes(apikeys) : new Elysia45,
38568
+ }) : new Elysia46,
38569
+ scim ? scimRoutes(scim) : new Elysia46,
38570
+ apikeys ? apiKeysRoutes(apikeys) : new Elysia46,
38528
38571
  oidcConfig ? oidcProviderRoutes({
38529
38572
  ...oidcConfig,
38530
38573
  authSessionStore
38531
- }) : new Elysia45,
38574
+ }) : new Elysia46,
38532
38575
  organizations ? organizationRoutes({
38533
38576
  ...organizations,
38534
38577
  authSessionStore,
38535
38578
  emit: auditEmit
38536
- }) : new Elysia45,
38579
+ }) : new Elysia46,
38537
38580
  roles ? roleRoutes({
38538
38581
  ...roles,
38539
38582
  authSessionStore,
38540
38583
  emit: auditEmit
38541
- }) : new Elysia45,
38542
- portal ? portalRoutes({ ...portal, emit: auditEmit }) : new Elysia45,
38584
+ }) : new Elysia46,
38585
+ portal ? portalRoutes({ ...portal, emit: auditEmit }) : new Elysia46,
38543
38586
  webauthn ? webauthnRoutes({
38544
38587
  ...webauthn,
38545
38588
  authSessionStore,
38546
38589
  cookieSecure: resolvedCookieSecure,
38547
38590
  emit: auditEmit
38548
- }) : new Elysia45,
38591
+ }) : new Elysia46,
38549
38592
  compliance ? complianceRoutes({
38550
38593
  ...compliance,
38551
38594
  authSessionStore,
38552
38595
  emit: auditEmit
38553
- }) : new Elysia45,
38596
+ }) : new Elysia46,
38554
38597
  createConfiguredAuthHtmxRoutes({ authSessionStore, config: htmx }),
38555
38598
  agentAuthRoutes(resolvedAgentAuth)
38556
38599
  ]);
@@ -38565,7 +38608,7 @@ var buildAuthApplications = async (configuration) => {
38565
38608
  };
38566
38609
  var auth = async (configuration) => {
38567
38610
  const { authContext, coreRoutes, featureRoutes } = await buildAuthApplications(configuration);
38568
- const application = new Elysia45({
38611
+ const application = new Elysia46({
38569
38612
  name: "@absolutejs/auth",
38570
38613
  seed: pluginDependencySeed(configuration)
38571
38614
  });
@@ -38733,6 +38776,7 @@ var createNodeSamlAdapter = async (options = {}) => {
38733
38776
  var auth2 = auth;
38734
38777
  export {
38735
38778
  userSessionIdTypebox,
38779
+ requireAuthPlugin,
38736
38780
  providers,
38737
38781
  protectRoutePlugin,
38738
38782
  isValidProviderOption,
@@ -38749,5 +38793,5 @@ export {
38749
38793
  VerificationProviderError
38750
38794
  };
38751
38795
 
38752
- //# debugId=E5516A34918E793A64756E2164756E21
38796
+ //# debugId=10D4FD2D81745E4B64756E2164756E21
38753
38797
  //# sourceMappingURL=server.js.map