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/README.md +4 -4
- package/dist/chunk-JWJJAIXV.js +6 -0
- package/dist/{chunk-3IDD2UXU.js.map → chunk-JWJJAIXV.js.map} +1 -1
- package/dist/cli.cjs +2 -2
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +2 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +397 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +358 -2
- package/dist/index.d.ts +358 -2
- package/dist/index.js +388 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-3IDD2UXU.js +0 -6
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { VERSION } from './chunk-
|
|
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
|