tempest-express-sdk 0.6.0 → 0.8.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,4 @@
1
- export { VERSION } from './chunk-3IDD2UXU.js';
1
+ export { VERSION } from './chunk-JWJJAIXV.js';
2
2
  import { AsyncLocalStorage } from 'async_hooks';
3
3
  import { extendZodWithOpenApi, OpenAPIRegistry, OpenApiGeneratorV31, OpenApiGeneratorV3 } from '@asteasolutions/zod-to-openapi';
4
4
  export { OpenAPIRegistry } from '@asteasolutions/zod-to-openapi';
@@ -7326,6 +7326,76 @@ function makeSessionMiddleware(service, options = {}) {
7326
7326
  };
7327
7327
  }
7328
7328
 
7329
+ // src/sessions/redisStore.ts
7330
+ var RedisSessionStore = class {
7331
+ /**
7332
+ * @param client - A connected node-redis v4 (or compatible) client.
7333
+ * @param prefix - Key prefix. Default `sess:`.
7334
+ */
7335
+ constructor(client, prefix = "sess:") {
7336
+ this.client = client;
7337
+ this.prefix = prefix;
7338
+ }
7339
+ client;
7340
+ prefix;
7341
+ key(idHash) {
7342
+ return `${this.prefix}${idHash}`;
7343
+ }
7344
+ userKey(userId) {
7345
+ return `${this.prefix}user:${userId}`;
7346
+ }
7347
+ async get(idHash) {
7348
+ const raw = await this.client.get(this.key(idHash));
7349
+ if (raw === null) return null;
7350
+ const session = JSON.parse(raw);
7351
+ if (session.expiresAt <= Date.now()) {
7352
+ await this.delete(idHash);
7353
+ return null;
7354
+ }
7355
+ return session;
7356
+ }
7357
+ async set(session) {
7358
+ const ttlSeconds = Math.max(1, Math.ceil((session.expiresAt - Date.now()) / 1e3));
7359
+ await this.client.set(this.key(session.idHash), JSON.stringify(session), {
7360
+ EX: ttlSeconds
7361
+ });
7362
+ await this.client.sAdd(this.userKey(session.userId), session.idHash);
7363
+ }
7364
+ async delete(idHash) {
7365
+ const raw = await this.client.get(this.key(idHash));
7366
+ await this.client.del(this.key(idHash));
7367
+ if (raw) {
7368
+ const session = JSON.parse(raw);
7369
+ await this.client.sRem(this.userKey(session.userId), idHash);
7370
+ }
7371
+ }
7372
+ async deleteByUser(userId) {
7373
+ const ids = await this.client.sMembers(this.userKey(userId));
7374
+ let count = 0;
7375
+ for (const idHash of ids) {
7376
+ await this.client.del(this.key(idHash));
7377
+ await this.client.sRem(this.userKey(userId), idHash);
7378
+ count += 1;
7379
+ }
7380
+ return count;
7381
+ }
7382
+ async listByUser(userId) {
7383
+ const ids = await this.client.sMembers(this.userKey(userId));
7384
+ const sessions = [];
7385
+ const now = Date.now();
7386
+ for (const idHash of ids) {
7387
+ const raw = await this.client.get(this.key(idHash));
7388
+ if (raw === null) {
7389
+ await this.client.sRem(this.userKey(userId), idHash);
7390
+ continue;
7391
+ }
7392
+ const session = JSON.parse(raw);
7393
+ if (session.expiresAt > now) sessions.push(session);
7394
+ }
7395
+ return sessions.sort((a, b) => a.createdAt - b.createdAt);
7396
+ }
7397
+ };
7398
+
7329
7399
  // src/sse/eventStream.ts
7330
7400
  var ServerSentEvent = class {
7331
7401
  constructor(init) {
@@ -7498,6 +7568,92 @@ var SSEBroker = class {
7498
7568
  }
7499
7569
  };
7500
7570
 
7571
+ // src/sse/redisBroker.ts
7572
+ var RedisSSEBroker = class {
7573
+ /**
7574
+ * @param publisher - The main Redis client (used to `publish`).
7575
+ * @param subscriber - A dedicated subscriber connection (`client.duplicate()`).
7576
+ * @param options - Channel prefix + per-stream options.
7577
+ */
7578
+ constructor(publisher, subscriber, options = {}) {
7579
+ this.publisher = publisher;
7580
+ this.subscriber = subscriber;
7581
+ this.prefix = options.prefix ?? "sse:";
7582
+ const { prefix: _p, ...streamOptions } = options;
7583
+ this.streamOptions = streamOptions;
7584
+ }
7585
+ publisher;
7586
+ subscriber;
7587
+ local = /* @__PURE__ */ new Map();
7588
+ prefix;
7589
+ streamOptions;
7590
+ channelKey(channel) {
7591
+ return `${this.prefix}${channel}`;
7592
+ }
7593
+ /** Emit a decoded payload to every local stream on a channel. */
7594
+ emitLocal(channel, data, event) {
7595
+ const set = this.local.get(channel);
7596
+ if (!set) return;
7597
+ for (const stream of set) stream.publish(data, event);
7598
+ }
7599
+ /**
7600
+ * Register a subscriber stream, subscribing to the Redis channel on first use.
7601
+ *
7602
+ * @param channel - The channel name.
7603
+ * @returns A fresh {@link EventStream} to serve to the client.
7604
+ */
7605
+ async register(channel) {
7606
+ const stream = new EventStream(this.streamOptions);
7607
+ let set = this.local.get(channel);
7608
+ if (!set) {
7609
+ set = /* @__PURE__ */ new Set();
7610
+ this.local.set(channel, set);
7611
+ await this.subscriber.subscribe(this.channelKey(channel), (raw) => {
7612
+ try {
7613
+ const { data, event } = JSON.parse(raw);
7614
+ this.emitLocal(channel, data, event);
7615
+ } catch {
7616
+ }
7617
+ });
7618
+ }
7619
+ set.add(stream);
7620
+ return stream;
7621
+ }
7622
+ /**
7623
+ * Remove a subscriber stream; unsubscribe from Redis when the last leaves.
7624
+ *
7625
+ * @param channel - The channel name.
7626
+ * @param stream - The stream to remove.
7627
+ */
7628
+ async unregister(channel, stream) {
7629
+ const set = this.local.get(channel);
7630
+ if (!set) return;
7631
+ set.delete(stream);
7632
+ stream.close();
7633
+ if (set.size === 0) {
7634
+ this.local.delete(channel);
7635
+ await this.subscriber.unsubscribe(this.channelKey(channel));
7636
+ }
7637
+ }
7638
+ /** Local subscriber count on `channel` (this replica only). */
7639
+ localSubscribers(channel) {
7640
+ return this.local.get(channel)?.size ?? 0;
7641
+ }
7642
+ /**
7643
+ * Publish to every subscriber across all replicas.
7644
+ *
7645
+ * @param channel - The channel name.
7646
+ * @param data - The payload (JSON-encoded).
7647
+ * @param event - Optional event name.
7648
+ */
7649
+ async publish(channel, data, event) {
7650
+ await this.publisher.publish(
7651
+ this.channelKey(channel),
7652
+ JSON.stringify({ data, ...event ? { event } : {} })
7653
+ );
7654
+ }
7655
+ };
7656
+
7501
7657
  // src/websockets/schemas.ts
7502
7658
  var wsEnvelopeSchema = z.object({
7503
7659
  type: z.string().openapi({ description: "Message type discriminator." }),
@@ -8512,6 +8668,17 @@ var authResponseSchema = z.object({
8512
8668
  user: userPublicSchema,
8513
8669
  tokens: tokenPairSchema
8514
8670
  }).openapi("AuthResponse");
8671
+ var mfaEnrollResponseSchema = z.object({
8672
+ secret: z.string().openapi({ description: "Base32 TOTP secret (manual entry)." }),
8673
+ otpauthUri: z.string().openapi({ description: "otpauth:// URI to render as QR." })
8674
+ }).openapi("MfaEnrollResponse");
8675
+ var mfaCodeSchema = z.object({ code: z.string().min(1).openapi({ description: "Authenticator code." }) }).openapi("MfaCode");
8676
+ var activationSchema = z.object({ token: z.string().min(1).openapi({ description: "Activation token." }) }).openapi("Activation");
8677
+ var passwordResetRequestSchema = z.object({ email: z.string().email().openapi({ description: "Account email." }) }).openapi("PasswordResetRequest");
8678
+ var passwordResetConfirmSchema = z.object({
8679
+ token: z.string().min(1).openapi({ description: "Reset token." }),
8680
+ password: z.string().min(1).openapi({ description: "New plaintext password." })
8681
+ }).openapi("PasswordResetConfirm");
8515
8682
 
8516
8683
  // src/auth/service.ts
8517
8684
  function toPublic(user) {
@@ -8624,6 +8791,178 @@ var UserAuthService = class {
8624
8791
  }
8625
8792
  };
8626
8793
 
8794
+ // src/auth/mfa.ts
8795
+ var MfaService = class {
8796
+ store;
8797
+ totp;
8798
+ /**
8799
+ * @param options - Store and TOTP helper.
8800
+ */
8801
+ constructor(options) {
8802
+ this.store = options.store;
8803
+ this.totp = options.totp;
8804
+ }
8805
+ /**
8806
+ * Begin enrollment: generate and persist a secret, return the QR URI.
8807
+ *
8808
+ * @param userId - The enrolling user.
8809
+ * @param accountName - Label shown in the authenticator (usually the email).
8810
+ * @returns The secret and provisioning URI.
8811
+ */
8812
+ async enroll(userId, accountName) {
8813
+ const secret = this.totp.generateSecret();
8814
+ await this.store.setSecret(userId, secret);
8815
+ await this.store.setEnabled(userId, false);
8816
+ return { secret, otpauthUri: this.totp.provisioningUri(secret, accountName) };
8817
+ }
8818
+ /**
8819
+ * Confirm enrollment by verifying a code, enabling MFA on success.
8820
+ *
8821
+ * @param userId - The user.
8822
+ * @param code - The 6-digit code from the authenticator.
8823
+ * @throws {ValidationException} When no secret is pending or the code is wrong.
8824
+ */
8825
+ async confirm(userId, code) {
8826
+ const secret = await this.store.getSecret(userId);
8827
+ if (!secret) throw new ValidationException({ message: "MFA not initialized" });
8828
+ if (!this.totp.verify(secret, code)) {
8829
+ throw new ValidationException({ message: "Invalid MFA code" });
8830
+ }
8831
+ await this.store.setEnabled(userId, true);
8832
+ }
8833
+ /**
8834
+ * Verify a code (login step). Returns `false` without throwing.
8835
+ *
8836
+ * @param userId - The user.
8837
+ * @param code - The submitted code.
8838
+ * @returns `true` when the code is valid.
8839
+ */
8840
+ async verify(userId, code) {
8841
+ const secret = await this.store.getSecret(userId);
8842
+ return secret ? this.totp.verify(secret, code) : false;
8843
+ }
8844
+ /**
8845
+ * Disable MFA after verifying a code.
8846
+ *
8847
+ * @param userId - The user.
8848
+ * @param code - The submitted code.
8849
+ * @throws {ValidationException} When the code is invalid.
8850
+ */
8851
+ async disable(userId, code) {
8852
+ if (!await this.verify(userId, code)) {
8853
+ throw new ValidationException({ message: "Invalid MFA code" });
8854
+ }
8855
+ await this.store.setEnabled(userId, false);
8856
+ await this.store.setSecret(userId, "");
8857
+ }
8858
+ };
8859
+
8860
+ // src/auth/activation.ts
8861
+ var ActivationService = class {
8862
+ store;
8863
+ ttlSeconds;
8864
+ /**
8865
+ * @param options - Store and token TTL.
8866
+ */
8867
+ constructor(options) {
8868
+ this.store = options.store;
8869
+ this.ttlSeconds = options.ttlSeconds ?? 60 * 60 * 24;
8870
+ }
8871
+ /**
8872
+ * Start activation: issue a token and persist its hash.
8873
+ *
8874
+ * @param userId - The user to activate.
8875
+ * @returns The one-time plaintext token (embed in the activation link).
8876
+ */
8877
+ async start(userId) {
8878
+ const { plaintext, tokenHash } = generateOpaqueToken();
8879
+ await this.store.saveActivationToken(
8880
+ userId,
8881
+ tokenHash,
8882
+ Date.now() + this.ttlSeconds * 1e3
8883
+ );
8884
+ return plaintext;
8885
+ }
8886
+ /**
8887
+ * Activate an account from a token.
8888
+ *
8889
+ * @param token - The plaintext token from the activation link.
8890
+ * @returns The activated user id.
8891
+ * @throws {InvalidTokenException} When the token is unknown or expired.
8892
+ */
8893
+ async activate(token) {
8894
+ const tokenHash = hashOpaqueToken(token);
8895
+ const record = await this.store.findActivationToken(tokenHash);
8896
+ if (!record || record.expiresAt <= Date.now()) {
8897
+ throw new InvalidTokenException({ message: "Invalid or expired activation token" });
8898
+ }
8899
+ await this.store.activate(record.userId);
8900
+ await this.store.clearActivationToken(tokenHash);
8901
+ return record.userId;
8902
+ }
8903
+ };
8904
+
8905
+ // src/auth/passwordReset.ts
8906
+ var PasswordResetService = class {
8907
+ store;
8908
+ password;
8909
+ ttlSeconds;
8910
+ passwordMinLength;
8911
+ /**
8912
+ * @param options - Store, password hasher and policy.
8913
+ */
8914
+ constructor(options) {
8915
+ this.store = options.store;
8916
+ this.password = options.password;
8917
+ this.ttlSeconds = options.ttlSeconds ?? 3600;
8918
+ this.passwordMinLength = options.passwordMinLength ?? 12;
8919
+ }
8920
+ /**
8921
+ * Request a reset for `email`.
8922
+ *
8923
+ * Returns the plaintext token only when the email maps to a user; otherwise
8924
+ * `null`. Callers should respond with the same success shape either way to
8925
+ * avoid user enumeration — email the token only when present.
8926
+ *
8927
+ * @param email - The account email.
8928
+ * @returns The one-time token, or `null` when no user matches.
8929
+ */
8930
+ async request(email) {
8931
+ const userId = await this.store.findUserIdByEmail(email.toLowerCase());
8932
+ if (!userId) return null;
8933
+ const { plaintext, tokenHash } = generateOpaqueToken();
8934
+ await this.store.saveResetToken(
8935
+ userId,
8936
+ tokenHash,
8937
+ Date.now() + this.ttlSeconds * 1e3
8938
+ );
8939
+ return plaintext;
8940
+ }
8941
+ /**
8942
+ * Confirm a reset: validate the token + new password and rehash.
8943
+ *
8944
+ * @param token - The plaintext reset token.
8945
+ * @param newPassword - The new plaintext password.
8946
+ * @throws {ValidationException} When the new password is too short.
8947
+ * @throws {InvalidTokenException} When the token is unknown or expired.
8948
+ */
8949
+ async confirm(token, newPassword) {
8950
+ if (newPassword.length < this.passwordMinLength) {
8951
+ throw new ValidationException({
8952
+ message: `Password must be at least ${this.passwordMinLength} characters`,
8953
+ details: { minLength: this.passwordMinLength }
8954
+ });
8955
+ }
8956
+ const tokenHash = hashOpaqueToken(token);
8957
+ const record = await this.store.findResetToken(tokenHash);
8958
+ if (!record || record.expiresAt <= Date.now()) {
8959
+ throw new InvalidTokenException({ message: "Invalid or expired reset token" });
8960
+ }
8961
+ await this.store.updatePassword(record.userId, await this.password.hash(newPassword));
8962
+ await this.store.clearResetToken(tokenHash);
8963
+ }
8964
+ };
8965
+
8627
8966
  // src/auth/middleware.ts
8628
8967
  function bearerToken(req) {
8629
8968
  const header = req.header("authorization");
@@ -8726,6 +9065,53 @@ function makeAuthRouter(options) {
8726
9065
  }
8727
9066
  res.json(claims);
8728
9067
  });
9068
+ if (options.activation) {
9069
+ const activation = options.activation;
9070
+ router.post(`${prefix}/activate`, async (req, res) => {
9071
+ const { token } = activationSchema.parse(req.body);
9072
+ const userId = await activation.activate(token);
9073
+ res.json({ activated: true, userId });
9074
+ });
9075
+ }
9076
+ if (options.passwordReset) {
9077
+ const reset = options.passwordReset;
9078
+ router.post(`${prefix}/password-reset/request`, async (req, res) => {
9079
+ const { email } = passwordResetRequestSchema.parse(req.body);
9080
+ const token = await reset.request(email);
9081
+ res.status(202).json({ requested: true, ...token ? { token } : {} });
9082
+ });
9083
+ router.post(`${prefix}/password-reset/confirm`, async (req, res) => {
9084
+ const { token, password } = passwordResetConfirmSchema.parse(req.body);
9085
+ await reset.confirm(token, password);
9086
+ res.json({ reset: true });
9087
+ });
9088
+ }
9089
+ if (options.mfa) {
9090
+ const mfa = options.mfa;
9091
+ const requireUser = (req) => {
9092
+ const claims = getAuth(req);
9093
+ if (!claims || typeof claims.sub !== "string") {
9094
+ throw new UnauthorizedException({ message: "Not authenticated" });
9095
+ }
9096
+ return claims.sub;
9097
+ };
9098
+ router.post(`${prefix}/mfa/enroll`, makeJwtAuthMiddleware(jwt), async (req, res) => {
9099
+ const claims = getAuth(req);
9100
+ const userId = requireUser(req);
9101
+ const label = typeof claims?.email === "string" ? claims.email : userId;
9102
+ res.json(await mfa.enroll(userId, label));
9103
+ });
9104
+ router.post(`${prefix}/mfa/confirm`, makeJwtAuthMiddleware(jwt), async (req, res) => {
9105
+ const { code } = mfaCodeSchema.parse(req.body);
9106
+ await mfa.confirm(requireUser(req), code);
9107
+ res.json({ enabled: true });
9108
+ });
9109
+ router.post(`${prefix}/mfa/disable`, makeJwtAuthMiddleware(jwt), async (req, res) => {
9110
+ const { code } = mfaCodeSchema.parse(req.body);
9111
+ await mfa.disable(requireUser(req), code);
9112
+ res.json({ enabled: false });
9113
+ });
9114
+ }
8729
9115
  return router;
8730
9116
  }
8731
9117
  var logger2 = new JSONLogger("tempest_express_sdk.api.handlers");
@@ -8993,6 +9379,6 @@ function runServer(app, options = {}) {
8993
9379
  });
8994
9380
  }
8995
9381
 
8996
- export { AdminSite, AppException, AttemptThrottle, BaseController, BaseModel, BaseService, CEP_PATTERN, CNPJ_PATTERN, CPF_PATTERN, CircuitOpenError, CompositeFeatureFlagBackend, ConflictException, DEFAULT_LOCALE, EmailUtils, EnvFeatureFlagBackend, EventStream, ExpiredTokenException, FeatureFlags, ForbiddenException, HTTPClient, HTTP_500_MARKER, InvalidTokenException, JSONLogger, JWTUtils, LocalUploadStorage, MemoryBroker, MemoryCacheManager, MemoryFeatureFlagBackend, MemorySessionStore, MemoryThrottleBackend, MessageCatalog, MetricsUtils, NotFoundException, PHONE_BR_PATTERN, PasswordUtils, REQUEST_ID_HEADER, RabbitBroker, RedisCacheManager, Region, RetryPolicy, SSEBroker, ServerSentEvent, SessionService, TOTPHelper, TaskManager, TelegramProvider, TooManyRequestsException, TwilioSmsProvider, UF, UnauthorizedException, UserAuthService, ValidationException, WebPushDispatcher, WebPushError, WebPushGoneError, WebSocketHub, WhatsAppProvider, attachWebSocketHub, authResponseSchema, baseAppSettingsSchema, baseAppSettingsShape, baseResponseSchema, bearerToken, buildContentDisposition, cached3 as cached, cepField, citiesByUf, cnpjField, coerceFlag, configureLogging, corsSettingsShape, cpfField, cpfOrCnpjField, createApp, createOpenApiRegistry, createdByColumn, cursorPaginationFilterSchema, cursorPaginationSchema, databaseSettingsShape, decodeCursor, defaultMessageCatalog, defineEnum, deletedAtColumn, encodeCursor, generateOpaqueToken, generateOpenApiDocument, getAuth, getClientIp, getConditions, getPaginationConditions, getRequestId, getState, hashOpaqueToken, inboundMessageSchema, isValidCep, isValidCity, isValidCnpj, isValidCpf, isValidCpfCnpj, isValidPhoneBr, isValidUf, listStates, loadSettings, loginSchema, makeAdminRouter, makeAppExceptionHandler, makeAuthRouter, makeFlagGuard, makeHealthRouter, makeJwtAuthMiddleware, makeSessionMiddleware, makeTwilioWebhookRouter, makeUnhandledExceptionHandler, makeWhatsAppWebhookRouter, modifyDict, mountOpenApiJson, mountRedoc, mountSwaggerUi, normalizeCep, normalizeCnpj, normalizeCpf, normalizeCpfCnpj, normalizePhoneBr, normalizeUf, notFoundHandler, onlyDigits, paginationFilterSchema, paginationSchema, parseAcceptLanguage, parseCookies, phoneBrField, refreshSchema, registerExceptionHandlers, requestIdMiddleware, requireRoles, runServer, runWithRequestContext, serverSettingsShape, sessionCookie, setRequestId, signupSchema, sseResponse, statesByRegion, tableNameFor, toDict, toUtc, tokenFromUrl, tokenPairSchema, ufField, updatedByColumn, userPublicSchema, utcnow, validateTwilioSignature, verifyOpaqueToken, webPushKeysSchema, webPushPayloadSchema, webPushSubscriptionSchema, wsEnvelopeSchema };
9382
+ export { ActivationService, AdminSite, AppException, AttemptThrottle, BaseController, BaseModel, BaseService, CEP_PATTERN, CNPJ_PATTERN, CPF_PATTERN, CircuitOpenError, CompositeFeatureFlagBackend, ConflictException, DEFAULT_LOCALE, EmailUtils, EnvFeatureFlagBackend, EventStream, ExpiredTokenException, FeatureFlags, ForbiddenException, HTTPClient, HTTP_500_MARKER, InvalidTokenException, JSONLogger, JWTUtils, LocalUploadStorage, MemoryBroker, MemoryCacheManager, MemoryFeatureFlagBackend, MemorySessionStore, MemoryThrottleBackend, MessageCatalog, MetricsUtils, MfaService, NotFoundException, PHONE_BR_PATTERN, PasswordResetService, PasswordUtils, REQUEST_ID_HEADER, RabbitBroker, RedisCacheManager, RedisSSEBroker, RedisSessionStore, Region, RetryPolicy, SSEBroker, ServerSentEvent, SessionService, TOTPHelper, TaskManager, TelegramProvider, TooManyRequestsException, TwilioSmsProvider, UF, UnauthorizedException, UserAuthService, ValidationException, WebPushDispatcher, WebPushError, WebPushGoneError, WebSocketHub, WhatsAppProvider, activationSchema, attachWebSocketHub, authResponseSchema, baseAppSettingsSchema, baseAppSettingsShape, baseResponseSchema, bearerToken, buildContentDisposition, cached3 as cached, cepField, citiesByUf, cnpjField, coerceFlag, configureLogging, corsSettingsShape, cpfField, cpfOrCnpjField, createApp, createOpenApiRegistry, createdByColumn, cursorPaginationFilterSchema, cursorPaginationSchema, databaseSettingsShape, decodeCursor, defaultMessageCatalog, defineEnum, deletedAtColumn, encodeCursor, generateOpaqueToken, generateOpenApiDocument, getAuth, getClientIp, getConditions, getPaginationConditions, getRequestId, getState, hashOpaqueToken, inboundMessageSchema, isValidCep, isValidCity, isValidCnpj, isValidCpf, isValidCpfCnpj, isValidPhoneBr, isValidUf, listStates, loadSettings, loginSchema, makeAdminRouter, makeAppExceptionHandler, makeAuthRouter, makeFlagGuard, makeHealthRouter, makeJwtAuthMiddleware, makeSessionMiddleware, makeTwilioWebhookRouter, makeUnhandledExceptionHandler, makeWhatsAppWebhookRouter, mfaCodeSchema, mfaEnrollResponseSchema, modifyDict, mountOpenApiJson, mountRedoc, mountSwaggerUi, normalizeCep, normalizeCnpj, normalizeCpf, normalizeCpfCnpj, normalizePhoneBr, normalizeUf, notFoundHandler, onlyDigits, paginationFilterSchema, paginationSchema, parseAcceptLanguage, parseCookies, passwordResetConfirmSchema, passwordResetRequestSchema, phoneBrField, refreshSchema, registerExceptionHandlers, requestIdMiddleware, requireRoles, runServer, runWithRequestContext, serverSettingsShape, sessionCookie, setRequestId, signupSchema, sseResponse, statesByRegion, tableNameFor, toDict, toUtc, tokenFromUrl, tokenPairSchema, ufField, updatedByColumn, userPublicSchema, utcnow, validateTwilioSignature, verifyOpaqueToken, webPushKeysSchema, webPushPayloadSchema, webPushSubscriptionSchema, wsEnvelopeSchema };
8997
9383
  //# sourceMappingURL=index.js.map
8998
9384
  //# sourceMappingURL=index.js.map