@nio-cli/cli 0.3.7 → 0.6.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/.env.example +88 -12
- package/Dockerfile.gateway +13 -5
- package/README.md +186 -78
- package/dist/adapters/lang/vendor.js +5 -10
- package/dist/adapters/lang/vendor.js.map +1 -1
- package/dist/adapters/pg/auth-event-repository.js +30 -0
- package/dist/adapters/pg/auth-event-repository.js.map +1 -0
- package/dist/adapters/pg/client.js +24 -4
- package/dist/adapters/pg/client.js.map +1 -1
- package/dist/adapters/pg/login-challenge-repository.js.map +1 -1
- package/dist/adapters/pg/login-ip-repository.js +26 -0
- package/dist/adapters/pg/login-ip-repository.js.map +1 -0
- package/dist/adapters/pg/user-repository.js +47 -18
- package/dist/adapters/pg/user-repository.js.map +1 -1
- package/dist/adapters/sms/whatsapp.js +83 -0
- package/dist/adapters/sms/whatsapp.js.map +1 -0
- package/dist/app/ai-client.js +2 -2
- package/dist/app/ai-client.js.map +1 -1
- package/dist/brand.js +1 -1
- package/dist/brand.js.map +1 -1
- package/dist/cli/commands/ai.js +2 -2
- package/dist/cli/commands/ai.js.map +1 -1
- package/dist/cli/commands/auth.js +27 -20
- package/dist/cli/commands/auth.js.map +1 -1
- package/dist/cli/commands/config.js +17 -7
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/docker.js +4 -4
- package/dist/cli/commands/docker.js.map +1 -1
- package/dist/cli/commands/docs/content.js +80 -11
- package/dist/cli/commands/docs/content.js.map +1 -1
- package/dist/cli/commands/exec.js +1 -12
- package/dist/cli/commands/exec.js.map +1 -1
- package/dist/cli/commands/init/index.js +1 -2
- package/dist/cli/commands/init/index.js.map +1 -1
- package/dist/cli/commands/init/provision-step.js +2 -20
- package/dist/cli/commands/init/provision-step.js.map +1 -1
- package/dist/cli/commands/plan.js +1 -12
- package/dist/cli/commands/plan.js.map +1 -1
- package/dist/cli/commands/security.js +82 -11
- package/dist/cli/commands/security.js.map +1 -1
- package/dist/cli/commands/sync.js +9 -19
- package/dist/cli/commands/sync.js.map +1 -1
- package/dist/cli/commands/validate-plan.js +1 -10
- package/dist/cli/commands/validate-plan.js.map +1 -1
- package/dist/cli/copy/flows.json +1 -2
- package/dist/cli/copy.js.map +1 -1
- package/dist/cli/flows/dependencies.js +0 -4
- package/dist/cli/flows/dependencies.js.map +1 -1
- package/dist/cli/help-guide.js +69 -0
- package/dist/cli/help-guide.js.map +1 -0
- package/dist/cli/program.js +3 -3
- package/dist/cli/program.js.map +1 -1
- package/dist/cli/ui/render.js +0 -27
- package/dist/cli/ui/render.js.map +1 -1
- package/dist/cli.js +10 -2
- package/dist/cli.js.map +1 -1
- package/dist/gateway/config.js +23 -1
- package/dist/gateway/config.js.map +1 -1
- package/dist/gateway/edge-filter.js +20 -3
- package/dist/gateway/edge-filter.js.map +1 -1
- package/dist/gateway/index.js +145 -22
- package/dist/gateway/index.js.map +1 -1
- package/dist/gateway/middleware/auth.js +15 -3
- package/dist/gateway/middleware/auth.js.map +1 -1
- package/dist/gateway/services/login.js +52 -17
- package/dist/gateway/services/login.js.map +1 -1
- package/dist/gateway/services/register.js +20 -0
- package/dist/gateway/services/register.js.map +1 -0
- package/dist/gateway/services/security.js +69 -16
- package/dist/gateway/services/security.js.map +1 -1
- package/dist/gateway/throttle.js +57 -0
- package/dist/gateway/throttle.js.map +1 -0
- package/dist/lib/auth/backup-codes.js +4 -4
- package/dist/lib/auth/backup-codes.js.map +1 -1
- package/dist/lib/auth/breach-check.js +58 -0
- package/dist/lib/auth/breach-check.js.map +1 -0
- package/dist/lib/auth/gateway-client.js +17 -2
- package/dist/lib/auth/gateway-client.js.map +1 -1
- package/dist/lib/auth/gateway-process.js +17 -2
- package/dist/lib/auth/gateway-process.js.map +1 -1
- package/dist/lib/auth/gateway-token.js +5 -2
- package/dist/lib/auth/gateway-token.js.map +1 -1
- package/dist/lib/auth/nio-config.js +57 -7
- package/dist/lib/auth/nio-config.js.map +1 -1
- package/dist/lib/auth/otp.js +3 -3
- package/dist/lib/auth/otp.js.map +1 -1
- package/dist/lib/auth/password.js +33 -10
- package/dist/lib/auth/password.js.map +1 -1
- package/dist/lib/auth/secrets.js +96 -0
- package/dist/lib/auth/secrets.js.map +1 -0
- package/dist/lib/auth/session-store.js +2 -2
- package/dist/lib/auth/session-store.js.map +1 -1
- package/dist/lib/clients/client-configs.js +81 -86
- package/dist/lib/clients/client-configs.js.map +1 -1
- package/dist/lib/clients/client-install.js +22 -4
- package/dist/lib/clients/client-install.js.map +1 -1
- package/dist/lib/deps/dependencies.js +0 -25
- package/dist/lib/deps/dependencies.js.map +1 -1
- package/dist/lib/deps/dependency-install.js +3 -23
- package/dist/lib/deps/dependency-install.js.map +1 -1
- package/dist/lib/exec/exec-delegate.js +69 -48
- package/dist/lib/exec/exec-delegate.js.map +1 -1
- package/dist/lib/exec/plan-delegate.js +25 -34
- package/dist/lib/exec/plan-delegate.js.map +1 -1
- package/dist/lib/exec/qwen-client.js +74 -0
- package/dist/lib/exec/qwen-client.js.map +1 -0
- package/dist/lib/exec/validate-plan-delegate.js +13 -30
- package/dist/lib/exec/validate-plan-delegate.js.map +1 -1
- package/dist/lib/fetch-zipball.js +59 -0
- package/dist/lib/fetch-zipball.js.map +1 -0
- package/dist/lib/load-env.js +17 -5
- package/dist/lib/load-env.js.map +1 -1
- package/dist/lib/open-url.js +5 -2
- package/dist/lib/open-url.js.map +1 -1
- package/dist/lib/proc.js +27 -0
- package/dist/lib/proc.js.map +1 -1
- package/dist/lib/provision/provision.js +2 -2
- package/dist/lib/provision/provision.js.map +1 -1
- package/dist/lib/skills/patterns.js +15 -24
- package/dist/lib/skills/patterns.js.map +1 -1
- package/dist/lib/skills/skills-cache.js +25 -12
- package/dist/lib/skills/skills-cache.js.map +1 -1
- package/dist/lib/skills/skills.js +1 -1
- package/dist/lib/skills/skills.js.map +1 -1
- package/dist/lib/version-check.js +1 -11
- package/dist/lib/version-check.js.map +1 -1
- package/dist/mcp-server.js +5 -17
- package/dist/mcp-server.js.map +1 -1
- package/dist/tools/delegate-exec.js +3 -10
- package/dist/tools/delegate-exec.js.map +1 -1
- package/dist/tools/plan.js +6 -13
- package/dist/tools/plan.js.map +1 -1
- package/dist/tools/validate-plan.js +6 -14
- package/dist/tools/validate-plan.js.map +1 -1
- package/dist/tui/app.js +102 -18
- package/dist/tui/app.js.map +1 -1
- package/dist/tui/components.js +161 -88
- package/dist/tui/components.js.map +1 -1
- package/dist/tui/launch.js +6 -1
- package/dist/tui/launch.js.map +1 -1
- package/dist/tui/opencode.js +27 -0
- package/dist/tui/opencode.js.map +1 -1
- package/dist/tui/palette.js +12 -5
- package/dist/tui/palette.js.map +1 -1
- package/dist/tui/prompt-input.js +168 -0
- package/dist/tui/prompt-input.js.map +1 -0
- package/dist/tui/state.js +252 -20
- package/dist/tui/state.js.map +1 -1
- package/dist/tui/test-utils.js +24 -0
- package/dist/tui/test-utils.js.map +1 -0
- package/dist/version.js +17 -6
- package/dist/version.js.map +1 -1
- package/docker/docker-compose.yml +56 -26
- package/docker/kong.yml +10 -0
- package/package.json +21 -12
- package/dist/adapters/sms/http-generic.js +0 -50
- package/dist/adapters/sms/http-generic.js.map +0 -1
- package/dist/cli/commands/clean.js +0 -108
- package/dist/cli/commands/clean.js.map +0 -1
- package/dist/lib/clients/hooks.js +0 -191
- package/dist/lib/clients/hooks.js.map +0 -1
- package/dist/lib/exec/exec-engines.js +0 -63
- package/dist/lib/exec/exec-engines.js.map +0 -1
|
@@ -2,12 +2,16 @@ import jwt from 'jsonwebtoken';
|
|
|
2
2
|
import { createUserRepository } from '../../adapters/pg/user-repository.js';
|
|
3
3
|
import { createAuthSessionRepository } from '../../adapters/pg/auth-session-repository.js';
|
|
4
4
|
import { createLoginChallengeRepository } from '../../adapters/pg/login-challenge-repository.js';
|
|
5
|
-
import {
|
|
5
|
+
import { createWhatsAppSender, smsMode } from '../../adapters/sms/whatsapp.js';
|
|
6
6
|
import { generateOtp, hashOtp, verifyOtp } from '../../lib/auth/otp.js';
|
|
7
7
|
import { verifyBackupCode, markUsed, countRemaining } from '../../lib/auth/backup-codes.js';
|
|
8
|
-
import {
|
|
8
|
+
import { JWT_EXPIRES_IN, JWT_ISSUER, JWT_AUDIENCE } from '../config.js';
|
|
9
|
+
import { jwtSigningKey } from '../../lib/auth/secrets.js';
|
|
10
|
+
import { smsAllowed } from '../throttle.js';
|
|
9
11
|
export const OTP_TTL_MS = 5 * 60 * 1000;
|
|
10
12
|
export const OTP_MAX_ATTEMPTS = 3;
|
|
13
|
+
export const CHALLENGE_MAX_ATTEMPTS = OTP_MAX_ATTEMPTS * 2;
|
|
14
|
+
export const MAX_SESSIONS_PER_USER = Math.max(1, Number(process.env.NIO_MAX_SESSIONS_PER_USER) || 5);
|
|
11
15
|
export function expiresInMs(spec) {
|
|
12
16
|
const m = /^(\d+)(s|m|h|d)$/.exec(spec.trim());
|
|
13
17
|
if (!m) {
|
|
@@ -31,12 +35,29 @@ export function challengeUsable(ch) {
|
|
|
31
35
|
return { ok: false, reason: 'expired' };
|
|
32
36
|
return { ok: true, ch };
|
|
33
37
|
}
|
|
38
|
+
async function pruneExcessSessions(sessions, userId) {
|
|
39
|
+
try {
|
|
40
|
+
const active = await sessions.listActiveByUser(userId);
|
|
41
|
+
await Promise.all(active.slice(MAX_SESSIONS_PER_USER).map((s) => sessions.revoke(s.id)));
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
}
|
|
45
|
+
}
|
|
34
46
|
export async function issueSession(user) {
|
|
35
47
|
await createUserRepository().touchLastSession(user.id);
|
|
36
48
|
const ms = expiresInMs(JWT_EXPIRES_IN);
|
|
37
49
|
const expiresAt = new Date(Date.now() + ms);
|
|
38
|
-
const
|
|
39
|
-
const
|
|
50
|
+
const sessions = createAuthSessionRepository();
|
|
51
|
+
const session = await sessions.create({ userId: user.id, expiresAt });
|
|
52
|
+
await pruneExcessSessions(sessions, user.id);
|
|
53
|
+
const { kid, secret } = jwtSigningKey();
|
|
54
|
+
const token = jwt.sign({ sub: String(user.id), jti: session.id }, secret, {
|
|
55
|
+
algorithm: 'HS256',
|
|
56
|
+
expiresIn: Math.floor(ms / 1000),
|
|
57
|
+
issuer: JWT_ISSUER,
|
|
58
|
+
audience: JWT_AUDIENCE,
|
|
59
|
+
...(kid ? { keyid: kid } : {}),
|
|
60
|
+
});
|
|
40
61
|
return { token, userId: user.id, name: user.name, sessionId: session.id, expiresAt };
|
|
41
62
|
}
|
|
42
63
|
export async function login(name, password, deps = {}) {
|
|
@@ -47,30 +68,36 @@ export async function login(name, password, deps = {}) {
|
|
|
47
68
|
if (!user.auth2 || !user.phone) {
|
|
48
69
|
return { ok: true, step: 'done', session: await issueSession(user) };
|
|
49
70
|
}
|
|
71
|
+
if (!smsAllowed(user.id, user.phone)) {
|
|
72
|
+
return { ok: false, reason: 'server_error', error: 'muitos códigos solicitados — aguarde alguns minutos.' };
|
|
73
|
+
}
|
|
50
74
|
const challenges = deps.challenges ?? createLoginChallengeRepository();
|
|
51
|
-
const sms = deps.sms ??
|
|
75
|
+
const sms = deps.sms ?? createWhatsAppSender();
|
|
52
76
|
const code = generateOtp();
|
|
53
77
|
const challenge = await challenges.create({
|
|
54
78
|
userId: user.id,
|
|
55
79
|
purpose: 'login',
|
|
56
80
|
codeHash: hashOtp(code),
|
|
57
|
-
channel: '
|
|
81
|
+
channel: 'whatsapp',
|
|
58
82
|
expiresAt: new Date(Date.now() + OTP_TTL_MS),
|
|
59
83
|
});
|
|
60
|
-
const sent = await sms.
|
|
84
|
+
const sent = await sms.sendOtp(user.phone, code);
|
|
61
85
|
if (sent.status === 'skipped') {
|
|
62
86
|
await challenges.consume(challenge.id).catch(() => { });
|
|
63
|
-
return { ok: false, reason: 'server_error', error: '2FA não configurado no servidor (
|
|
87
|
+
return { ok: false, reason: 'server_error', error: '2FA não configurado no servidor (WHATSAPP_*).' };
|
|
64
88
|
}
|
|
65
89
|
if (sent.status === 'failed') {
|
|
66
90
|
await challenges.consume(challenge.id).catch(() => { });
|
|
67
|
-
return { ok: false, reason: 'server_error', error: `falha ao enviar o
|
|
91
|
+
return { ok: false, reason: 'server_error', error: `falha ao enviar o WhatsApp: ${sent.error ?? ''}`.trim() };
|
|
68
92
|
}
|
|
93
|
+
const mode = smsMode();
|
|
69
94
|
return {
|
|
70
95
|
ok: true,
|
|
71
96
|
step: '2fa_required',
|
|
72
97
|
challengeId: challenge.id,
|
|
73
98
|
phoneHint: maskPhone(user.phone),
|
|
99
|
+
smsMode: mode,
|
|
100
|
+
...(mode === 'echo' ? { devCode: code } : {}),
|
|
74
101
|
};
|
|
75
102
|
}
|
|
76
103
|
export async function verifyLogin(challengeId, code, type, deps = {}) {
|
|
@@ -82,18 +109,23 @@ export async function verifyLogin(challengeId, code, type, deps = {}) {
|
|
|
82
109
|
const ch = usable.ch;
|
|
83
110
|
const user = await users.findById(ch.userId);
|
|
84
111
|
if (!user)
|
|
85
|
-
return { ok: false, reason: 'not_found' };
|
|
112
|
+
return { ok: false, reason: 'not_found', userId: ch.userId };
|
|
86
113
|
if (type === 'backup') {
|
|
87
114
|
const stored = await users.getBackupCodes(ch.userId);
|
|
88
|
-
const idx = await verifyBackupCode(code, stored);
|
|
89
|
-
if (idx < 0)
|
|
90
|
-
|
|
91
|
-
|
|
115
|
+
const idx = await verifyBackupCode(code, stored.codes, stored.pepperId);
|
|
116
|
+
if (idx < 0) {
|
|
117
|
+
const attempts = await challenges.incrementAttempts(ch.id);
|
|
118
|
+
if (attempts >= CHALLENGE_MAX_ATTEMPTS)
|
|
119
|
+
return { ok: false, reason: 'attempts_exhausted', userId: ch.userId };
|
|
120
|
+
return { ok: false, reason: 'invalid', remaining: CHALLENGE_MAX_ATTEMPTS - attempts, userId: ch.userId };
|
|
121
|
+
}
|
|
122
|
+
const used = markUsed(stored.codes, idx);
|
|
123
|
+
await users.updateBackupCodes(ch.userId, used, stored.pepperId);
|
|
92
124
|
await challenges.consume(ch.id);
|
|
93
125
|
return {
|
|
94
126
|
ok: true,
|
|
95
127
|
session: await issueSession(user),
|
|
96
|
-
backupCodesRemaining: countRemaining(
|
|
128
|
+
backupCodesRemaining: countRemaining(used),
|
|
97
129
|
};
|
|
98
130
|
}
|
|
99
131
|
if (verifyOtp(code, ch.codeHash)) {
|
|
@@ -102,11 +134,14 @@ export async function verifyLogin(challengeId, code, type, deps = {}) {
|
|
|
102
134
|
}
|
|
103
135
|
const attempts = await challenges.incrementAttempts(ch.id);
|
|
104
136
|
if (attempts >= OTP_MAX_ATTEMPTS) {
|
|
105
|
-
return { ok: false, reason: 'attempts_exhausted', requiresBackupCode: true };
|
|
137
|
+
return { ok: false, reason: 'attempts_exhausted', requiresBackupCode: true, userId: ch.userId };
|
|
106
138
|
}
|
|
107
|
-
return { ok: false, reason: 'invalid', remaining: OTP_MAX_ATTEMPTS - attempts };
|
|
139
|
+
return { ok: false, reason: 'invalid', remaining: OTP_MAX_ATTEMPTS - attempts, userId: ch.userId };
|
|
108
140
|
}
|
|
109
141
|
export async function logout(sessionId) {
|
|
110
142
|
await createAuthSessionRepository().revoke(sessionId);
|
|
111
143
|
}
|
|
144
|
+
export async function logoutAll(userId) {
|
|
145
|
+
await createAuthSessionRepository().revokeAllByUser(userId);
|
|
146
|
+
}
|
|
112
147
|
//# sourceMappingURL=login.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/gateway/services/login.ts"],"names":[],"mappings":"AAKA,OAAO,GAAG,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../../src/gateway/services/login.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createUserRepository } from '../../adapters/pg/user-repository.js';
|
|
2
|
+
import { hashPassword, MIN_PASSWORD_LENGTH } from '../../lib/auth/password.js';
|
|
3
|
+
import { checkPasswordBreach } from '../../lib/auth/breach-check.js';
|
|
4
|
+
export async function register(name, password, deps = {}) {
|
|
5
|
+
const users = deps.users ?? createUserRepository();
|
|
6
|
+
const clean = name.trim();
|
|
7
|
+
if (!clean || clean.length > 64)
|
|
8
|
+
return { ok: false, reason: 'invalid_name' };
|
|
9
|
+
if (password.length < MIN_PASSWORD_LENGTH)
|
|
10
|
+
return { ok: false, reason: 'weak_password' };
|
|
11
|
+
if ((await checkPasswordBreach(password)).breached)
|
|
12
|
+
return { ok: false, reason: 'breached_password' };
|
|
13
|
+
if (await users.findByName(clean)) {
|
|
14
|
+
await hashPassword(password).catch(() => { });
|
|
15
|
+
return { ok: false, reason: 'name_taken' };
|
|
16
|
+
}
|
|
17
|
+
const user = await users.create({ name: clean, password });
|
|
18
|
+
return { ok: true, userId: user.id, name: user.name };
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"register.js","sourceRoot":"","sources":["../../../src/gateway/services/register.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,oBAAoB,EAAE,MAAM,sCAAsC,CAAC;AAC5E,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAMrE,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,IAAY,EACZ,QAAgB,EAChB,OAAmC,EAAE;IAErC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,oBAAoB,EAAE,CAAC;IACnD,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC1B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;IAC9E,IAAI,QAAQ,CAAC,MAAM,GAAG,mBAAmB;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAGzF,IAAI,CAAC,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;IACtG,IAAI,MAAM,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAIlC,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC7C,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAC7C,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC3D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;AACxD,CAAC"}
|
|
@@ -1,35 +1,73 @@
|
|
|
1
1
|
import { createUserRepository } from '../../adapters/pg/user-repository.js';
|
|
2
2
|
import { createLoginChallengeRepository } from '../../adapters/pg/login-challenge-repository.js';
|
|
3
|
-
import {
|
|
3
|
+
import { createLoginIpRepository } from '../../adapters/pg/login-ip-repository.js';
|
|
4
|
+
import { createAuthEventRepository } from '../../adapters/pg/auth-event-repository.js';
|
|
5
|
+
import { createAuthSessionRepository } from '../../adapters/pg/auth-session-repository.js';
|
|
6
|
+
import { createWhatsAppSender, smsMode, smsProviderHost } from '../../adapters/sms/whatsapp.js';
|
|
7
|
+
import { hashPassword, MIN_PASSWORD_LENGTH } from '../../lib/auth/password.js';
|
|
8
|
+
import { checkPasswordBreach } from '../../lib/auth/breach-check.js';
|
|
4
9
|
import { generateOtp, hashOtp, verifyOtp } from '../../lib/auth/otp.js';
|
|
5
10
|
import { generateBackupCodes, verifyBackupCode, markUsed, countRemaining, } from '../../lib/auth/backup-codes.js';
|
|
6
11
|
import { challengeUsable, maskPhone, OTP_TTL_MS, OTP_MAX_ATTEMPTS } from './login.js';
|
|
12
|
+
import { smsAllowed } from '../throttle.js';
|
|
13
|
+
import { currentPepperId } from '../../lib/auth/secrets.js';
|
|
14
|
+
export async function changePassword(userId, currentPassword, newPassword, deps = {}) {
|
|
15
|
+
if (newPassword.length < MIN_PASSWORD_LENGTH) {
|
|
16
|
+
return { ok: false, error: `senha nova muito curta (mínimo ${MIN_PASSWORD_LENGTH} caracteres)` };
|
|
17
|
+
}
|
|
18
|
+
if (newPassword === currentPassword) {
|
|
19
|
+
return { ok: false, error: 'a senha nova é igual à atual' };
|
|
20
|
+
}
|
|
21
|
+
if ((await checkPasswordBreach(newPassword)).breached) {
|
|
22
|
+
return { ok: false, error: 'senha nova apareceu em vazamento de dados conhecido — escolha outra' };
|
|
23
|
+
}
|
|
24
|
+
const users = deps.users ?? createUserRepository();
|
|
25
|
+
const user = await users.findById(userId);
|
|
26
|
+
if (!user)
|
|
27
|
+
return { ok: false, error: 'usuário não encontrado' };
|
|
28
|
+
if (!(await users.verifyCredentials(user.name, currentPassword))) {
|
|
29
|
+
return { ok: false, error: 'senha atual incorreta' };
|
|
30
|
+
}
|
|
31
|
+
const { phc, pepperId } = await hashPassword(newPassword);
|
|
32
|
+
await users.updatePasswordHash(userId, phc, pepperId);
|
|
33
|
+
await (deps.authSessions ?? createAuthSessionRepository()).revokeAllByUser(userId);
|
|
34
|
+
return { ok: true };
|
|
35
|
+
}
|
|
7
36
|
export function isE164(phone) {
|
|
8
37
|
return /^\+\d{8,15}$/.test(phone.trim());
|
|
9
38
|
}
|
|
10
39
|
export async function startSecurityChallenge(userId, toPhone, deps = {}) {
|
|
11
40
|
if (!isE164(toPhone))
|
|
12
41
|
return { ok: false, error: 'número inválido (use E.164, ex.: +5511999998888)' };
|
|
42
|
+
if (!smsAllowed(userId, toPhone)) {
|
|
43
|
+
return { ok: false, error: 'muitos códigos solicitados — aguarde alguns minutos.' };
|
|
44
|
+
}
|
|
13
45
|
const challenges = deps.challenges ?? createLoginChallengeRepository();
|
|
14
|
-
const sms = deps.sms ??
|
|
46
|
+
const sms = deps.sms ?? createWhatsAppSender();
|
|
15
47
|
const code = generateOtp();
|
|
16
48
|
const challenge = await challenges.create({
|
|
17
49
|
userId,
|
|
18
50
|
purpose: 'enable_2fa',
|
|
19
51
|
codeHash: hashOtp(code),
|
|
20
|
-
channel: '
|
|
52
|
+
channel: 'whatsapp',
|
|
21
53
|
expiresAt: new Date(Date.now() + OTP_TTL_MS),
|
|
22
54
|
});
|
|
23
|
-
const sent = await sms.
|
|
55
|
+
const sent = await sms.sendOtp(toPhone, code);
|
|
24
56
|
if (sent.status === 'skipped') {
|
|
25
57
|
await challenges.consume(challenge.id).catch(() => { });
|
|
26
|
-
return { ok: false, error: '2FA não configurado no servidor (
|
|
58
|
+
return { ok: false, error: '2FA não configurado no servidor (WHATSAPP_*).' };
|
|
27
59
|
}
|
|
28
60
|
if (sent.status === 'failed') {
|
|
29
61
|
await challenges.consume(challenge.id).catch(() => { });
|
|
30
|
-
return { ok: false, error: `falha ao enviar o
|
|
62
|
+
return { ok: false, error: `falha ao enviar o WhatsApp: ${sent.error ?? ''}`.trim() };
|
|
31
63
|
}
|
|
32
|
-
|
|
64
|
+
const mode = smsMode();
|
|
65
|
+
return {
|
|
66
|
+
ok: true,
|
|
67
|
+
challengeId: challenge.id,
|
|
68
|
+
smsMode: mode,
|
|
69
|
+
...(mode === 'echo' ? { devCode: code } : {}),
|
|
70
|
+
};
|
|
33
71
|
}
|
|
34
72
|
async function consumeSecurityCode(userId, challengeId, code, type, deps) {
|
|
35
73
|
const challenges = deps.challenges ?? createLoginChallengeRepository();
|
|
@@ -43,10 +81,10 @@ async function consumeSecurityCode(userId, challengeId, code, type, deps) {
|
|
|
43
81
|
}
|
|
44
82
|
if (type === 'backup') {
|
|
45
83
|
const stored = await users.getBackupCodes(userId);
|
|
46
|
-
const idx = await verifyBackupCode(code, stored);
|
|
84
|
+
const idx = await verifyBackupCode(code, stored.codes, stored.pepperId);
|
|
47
85
|
if (idx < 0)
|
|
48
86
|
return { ok: false, error: 'código de backup inválido' };
|
|
49
|
-
await users.updateBackupCodes(userId, markUsed(stored, idx));
|
|
87
|
+
await users.updateBackupCodes(userId, markUsed(stored.codes, idx), stored.pepperId);
|
|
50
88
|
}
|
|
51
89
|
else {
|
|
52
90
|
if (!verifyOtp(code, ch.codeHash)) {
|
|
@@ -65,8 +103,8 @@ export async function confirmEnable2fa(userId, challengeId, code, phone, deps =
|
|
|
65
103
|
if (!res.ok)
|
|
66
104
|
return res;
|
|
67
105
|
const users = deps.users ?? createUserRepository();
|
|
68
|
-
const { codes, hashes } = await generateBackupCodes();
|
|
69
|
-
await users.enable2fa(userId, phone.trim(), hashes);
|
|
106
|
+
const { codes, hashes, pepperId } = await generateBackupCodes();
|
|
107
|
+
await users.enable2fa(userId, phone.trim(), hashes, pepperId);
|
|
70
108
|
return { ok: true, backupCodes: codes };
|
|
71
109
|
}
|
|
72
110
|
export async function disable2fa(userId, challengeId, code, type, deps = {}) {
|
|
@@ -81,19 +119,34 @@ export async function regenerateBackupCodes(userId, challengeId, code, type, dep
|
|
|
81
119
|
if (!res.ok)
|
|
82
120
|
return res;
|
|
83
121
|
const users = deps.users ?? createUserRepository();
|
|
84
|
-
const { codes, hashes } = await generateBackupCodes();
|
|
85
|
-
await users.updateBackupCodes(userId, hashes);
|
|
122
|
+
const { codes, hashes, pepperId } = await generateBackupCodes();
|
|
123
|
+
await users.updateBackupCodes(userId, hashes, pepperId);
|
|
86
124
|
return { ok: true, backupCodes: codes };
|
|
87
125
|
}
|
|
88
126
|
export async function status(userId, deps = {}) {
|
|
89
127
|
const users = deps.users ?? createUserRepository();
|
|
128
|
+
const loginIps = deps.loginIps ?? createLoginIpRepository();
|
|
129
|
+
const authEvents = deps.authEvents ?? createAuthEventRepository();
|
|
130
|
+
const recentIps = (await loginIps.recent(userId, 10).catch(() => [])).map((e) => ({
|
|
131
|
+
ip: e.ip,
|
|
132
|
+
lastSeen: e.lastSeen.toISOString(),
|
|
133
|
+
count: e.count,
|
|
134
|
+
}));
|
|
135
|
+
const recentFailedAttempts = (await authEvents.recentFailures({ userId, limit: 5 }).catch(() => [])).map((f) => ({ at: f.at.toISOString(), event: f.event, ip: f.ip }));
|
|
136
|
+
const sms = { mode: smsMode(), host: smsProviderHost() };
|
|
90
137
|
const user = await users.findById(userId);
|
|
91
|
-
if (!user || !user.auth2)
|
|
92
|
-
return { enabled: false, phoneHint: null, backupCodesRemaining: 0 };
|
|
138
|
+
if (!user || !user.auth2) {
|
|
139
|
+
return { enabled: false, phoneHint: null, backupCodesRemaining: 0, recentIps, recentFailedAttempts, sms };
|
|
140
|
+
}
|
|
141
|
+
const stored = await users.getBackupCodes(userId);
|
|
93
142
|
return {
|
|
94
143
|
enabled: true,
|
|
95
144
|
phoneHint: user.phone ? maskPhone(user.phone) : null,
|
|
96
|
-
backupCodesRemaining: countRemaining(
|
|
145
|
+
backupCodesRemaining: countRemaining(stored.codes),
|
|
146
|
+
regenerateBackupCodesRecommended: stored.codes != null && stored.pepperId !== currentPepperId() ? true : undefined,
|
|
147
|
+
recentIps,
|
|
148
|
+
recentFailedAttempts,
|
|
149
|
+
sms,
|
|
97
150
|
};
|
|
98
151
|
}
|
|
99
152
|
//# sourceMappingURL=security.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../../src/gateway/services/security.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"security.js","sourceRoot":"","sources":["../../../src/gateway/services/security.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
const windows = new Map();
|
|
2
|
+
export function hit(key, limit, windowMs, now = Date.now()) {
|
|
3
|
+
const w = windows.get(key);
|
|
4
|
+
if (!w || now >= w.resetAt) {
|
|
5
|
+
windows.set(key, { count: 1, resetAt: now + windowMs });
|
|
6
|
+
return { ok: true, retryAfterMs: 0 };
|
|
7
|
+
}
|
|
8
|
+
w.count++;
|
|
9
|
+
if (w.count <= limit)
|
|
10
|
+
return { ok: true, retryAfterMs: 0 };
|
|
11
|
+
return { ok: false, retryAfterMs: w.resetAt - now };
|
|
12
|
+
}
|
|
13
|
+
export const SMS_PER_USER = 3;
|
|
14
|
+
export const SMS_USER_WINDOW_MS = 15 * 60 * 1000;
|
|
15
|
+
export const SMS_PHONE_WINDOW_MS = 60 * 1000;
|
|
16
|
+
export function smsAllowed(userId, phone, now = Date.now()) {
|
|
17
|
+
const perUser = hit(`sms:u:${userId}`, SMS_PER_USER, SMS_USER_WINDOW_MS, now);
|
|
18
|
+
const perPhone = hit(`sms:p:${phone}`, 1, SMS_PHONE_WINDOW_MS, now);
|
|
19
|
+
return perUser.ok && perPhone.ok;
|
|
20
|
+
}
|
|
21
|
+
const loginFails = new Map();
|
|
22
|
+
const LOGIN_FAIL_TTL_MS = 60 * 60 * 1000;
|
|
23
|
+
const LOGIN_MAX_DELAY_MS = 20_000;
|
|
24
|
+
const LOGIN_FREE_ATTEMPTS = 4;
|
|
25
|
+
export function loginDelayMs(key, now = Date.now()) {
|
|
26
|
+
const f = loginFails.get(key);
|
|
27
|
+
if (!f || now >= f.expiresAt || f.n <= LOGIN_FREE_ATTEMPTS)
|
|
28
|
+
return 0;
|
|
29
|
+
const step = f.n - LOGIN_FREE_ATTEMPTS;
|
|
30
|
+
return Math.min(2 ** (step - 1) * 500, LOGIN_MAX_DELAY_MS);
|
|
31
|
+
}
|
|
32
|
+
export function recordLoginFail(key, now = Date.now()) {
|
|
33
|
+
const f = loginFails.get(key);
|
|
34
|
+
if (f && now < f.expiresAt) {
|
|
35
|
+
f.n++;
|
|
36
|
+
f.expiresAt = now + LOGIN_FAIL_TTL_MS;
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
loginFails.set(key, { n: 1, expiresAt: now + LOGIN_FAIL_TTL_MS });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function recordLoginOk(key) {
|
|
43
|
+
loginFails.delete(key);
|
|
44
|
+
}
|
|
45
|
+
export function sweep(now = Date.now()) {
|
|
46
|
+
for (const [k, w] of windows)
|
|
47
|
+
if (now >= w.resetAt)
|
|
48
|
+
windows.delete(k);
|
|
49
|
+
for (const [k, f] of loginFails)
|
|
50
|
+
if (now >= f.expiresAt)
|
|
51
|
+
loginFails.delete(k);
|
|
52
|
+
}
|
|
53
|
+
export function __clear() {
|
|
54
|
+
windows.clear();
|
|
55
|
+
loginFails.clear();
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=throttle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"throttle.js","sourceRoot":"","sources":["../../src/gateway/throttle.ts"],"names":[],"mappings":"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"}
|
|
@@ -12,10 +12,10 @@ function randomCode() {
|
|
|
12
12
|
}
|
|
13
13
|
export async function generateBackupCodes() {
|
|
14
14
|
const codes = Array.from({ length: COUNT }, randomCode);
|
|
15
|
-
const
|
|
16
|
-
return { codes, hashes:
|
|
15
|
+
const hashed = await Promise.all(codes.map((c) => hashPassword(c)));
|
|
16
|
+
return { codes, hashes: hashed.map((h) => h.phc).join('|'), pepperId: hashed[0].pepperId };
|
|
17
17
|
}
|
|
18
|
-
export async function verifyBackupCode(input, joined) {
|
|
18
|
+
export async function verifyBackupCode(input, joined, pepperId) {
|
|
19
19
|
if (!joined)
|
|
20
20
|
return -1;
|
|
21
21
|
const normalized = input.trim().toUpperCase();
|
|
@@ -24,7 +24,7 @@ export async function verifyBackupCode(input, joined) {
|
|
|
24
24
|
const h = parts[i];
|
|
25
25
|
if (!h || h === USED)
|
|
26
26
|
continue;
|
|
27
|
-
if (await verifyPassword(h, normalized))
|
|
27
|
+
if (await verifyPassword(h, normalized, pepperId))
|
|
28
28
|
return i;
|
|
29
29
|
}
|
|
30
30
|
return -1;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"backup-codes.js","sourceRoot":"","sources":["../../../src/lib/auth/backup-codes.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"backup-codes.js","sourceRoot":"","sources":["../../../src/lib/auth/backup-codes.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE7D,MAAM,KAAK,GAAG,EAAE,CAAC;AACjB,MAAM,MAAM,GAAG,CAAC,CAAC;AAEjB,MAAM,QAAQ,GAAG,iCAAiC,CAAC;AACnD,MAAM,IAAI,GAAG,QAAQ,CAAC;AAEtB,SAAS,UAAU;IACjB,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC,EAAE;QAAE,GAAG,IAAI,QAAQ,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAChF,OAAO,GAAG,CAAC;AACb,CAAC;AAGD,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,UAAU,CAAC,CAAC;IACxD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACpE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAE,CAAC,QAAQ,EAAE,CAAC;AAC9F,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,KAAa,EACb,MAAqB,EACrB,QAAgB;IAEhB,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC,CAAC;IACvB,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACnB,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI;YAAE,SAAS;QAC/B,IAAI,MAAM,cAAc,CAAC,CAAC,EAAE,UAAU,EAAE,QAAQ,CAAC;YAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;IACD,OAAO,CAAC,CAAC,CAAC;AACZ,CAAC;AAGD,MAAM,UAAU,QAAQ,CAAC,MAAc,EAAE,GAAW;IAClD,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG,KAAK,CAAC,MAAM;QAAE,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IACtD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAGD,MAAM,UAAU,cAAc,CAAC,MAAqB;IAClD,IAAI,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IACtB,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC;AACjE,CAAC;AAGD,MAAM,UAAU,kBAAkB,CAAC,CAAS;IAC1C,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
const COMMON = new Set([
|
|
3
|
+
'123456', '123456789', '12345678', '1234567', '12345', '1234567890', '123123', '111111',
|
|
4
|
+
'000000', '654321', '666666', '888888', '1234', '12345678910', '121212', '112233',
|
|
5
|
+
'password', 'password1', 'password123', 'passw0rd', 'senha', 'senha123', 'minhasenha',
|
|
6
|
+
'qwerty', 'qwerty123', 'qwertyuiop', 'asdfghjkl', 'zxcvbnm', '1q2w3e4r', '1q2w3e4r5t',
|
|
7
|
+
'admin', 'admin123', 'administrator', 'root', 'toor', 'user', 'guest', 'test', 'test123',
|
|
8
|
+
'welcome', 'welcome1', 'letmein', 'iloveyou', 'monkey', 'dragon', 'sunshine', 'princess',
|
|
9
|
+
'football', 'baseball', 'superman', 'batman', 'trustno1', 'master', 'shadow', 'michael',
|
|
10
|
+
'jennifer', 'jordan', 'harley', 'hunter', 'ranger', 'buster', 'thomas', 'robert', 'daniel',
|
|
11
|
+
'ashley', 'nicole', 'chelsea', 'matthew', 'access', 'flower', 'hottie', 'loveme', 'zaq1zaq1',
|
|
12
|
+
'abc123', 'abcd1234', 'abcdef', 'a1b2c3d4', 'qazwsx', 'qazwsxedc', 'asdf1234', 'p@ssw0rd',
|
|
13
|
+
'changeme', 'secret', 'whatever', 'freedom', 'starwars', 'computer', 'internet', 'samsung',
|
|
14
|
+
'google', 'facebook', 'linkedin', 'nintendo', 'pokemon', 'mustang', 'corvette', 'ferrari',
|
|
15
|
+
'brasil', 'brazil', 'flamengo', 'corinthians', 'palmeiras', 'saopaulo', 'gremio',
|
|
16
|
+
'deus', 'jesus', 'amor', 'familia', 'cachorro', 'gabriel', 'rafael', 'fernanda', 'juliana',
|
|
17
|
+
]);
|
|
18
|
+
function hibpTimeoutMs() {
|
|
19
|
+
return Math.max(200, Number(process.env.NIO_HIBP_TIMEOUT_MS) || 1500);
|
|
20
|
+
}
|
|
21
|
+
function hibpDisabled() {
|
|
22
|
+
return /^(1|true|yes|on)$/i.test((process.env.NIO_HIBP_DISABLE ?? '').trim());
|
|
23
|
+
}
|
|
24
|
+
function sha1Upper(input) {
|
|
25
|
+
return createHash('sha1').update(input, 'utf8').digest('hex').toUpperCase();
|
|
26
|
+
}
|
|
27
|
+
export async function checkPasswordBreach(password) {
|
|
28
|
+
if (COMMON.has(password.toLowerCase()))
|
|
29
|
+
return { breached: true, source: 'common' };
|
|
30
|
+
if (hibpDisabled())
|
|
31
|
+
return { breached: false };
|
|
32
|
+
const hash = sha1Upper(password);
|
|
33
|
+
const prefix = hash.slice(0, 5);
|
|
34
|
+
const suffix = hash.slice(5);
|
|
35
|
+
const ac = new AbortController();
|
|
36
|
+
const timer = setTimeout(() => ac.abort(), hibpTimeoutMs());
|
|
37
|
+
try {
|
|
38
|
+
const res = await fetch(`https://api.pwnedpasswords.com/range/${prefix}`, {
|
|
39
|
+
signal: ac.signal,
|
|
40
|
+
headers: { 'Add-Padding': 'true' },
|
|
41
|
+
});
|
|
42
|
+
if (!res.ok)
|
|
43
|
+
return { breached: false };
|
|
44
|
+
for (const line of (await res.text()).split('\n')) {
|
|
45
|
+
const [lineSuffix, countStr] = line.trim().split(':');
|
|
46
|
+
if (lineSuffix === suffix && Number(countStr) > 0)
|
|
47
|
+
return { breached: true, source: 'pwned' };
|
|
48
|
+
}
|
|
49
|
+
return { breached: false };
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return { breached: false };
|
|
53
|
+
}
|
|
54
|
+
finally {
|
|
55
|
+
clearTimeout(timer);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=breach-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"breach-check.js","sourceRoot":"","sources":["../../../src/lib/auth/breach-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,6 +33,15 @@ async function post(path, body, headers) {
|
|
|
33
33
|
throw await errorFromResponse(res);
|
|
34
34
|
return (await res.json());
|
|
35
35
|
}
|
|
36
|
+
export async function gatewayRegister(name, password) {
|
|
37
|
+
const res = await gwFetch('POST', '/register', {
|
|
38
|
+
headers: await baseHeaders(),
|
|
39
|
+
body: JSON.stringify({ name, password }),
|
|
40
|
+
});
|
|
41
|
+
if (!res.ok)
|
|
42
|
+
throw await errorFromResponse(res);
|
|
43
|
+
return (await res.json());
|
|
44
|
+
}
|
|
36
45
|
export async function gatewayLogin(name, password) {
|
|
37
46
|
const res = await gwFetch('POST', '/login', {
|
|
38
47
|
headers: await baseHeaders(),
|
|
@@ -62,14 +71,19 @@ export async function gatewayVerify2fa(challengeId, code, type) {
|
|
|
62
71
|
throw new Error(body.error ?? `gateway respondeu ${res.status}`);
|
|
63
72
|
return { ok: true, ...body, backupCodesRemaining: body.backupCodesRemaining };
|
|
64
73
|
}
|
|
65
|
-
export async function gatewayLogout(sessionId) {
|
|
74
|
+
export async function gatewayLogout(sessionId, token) {
|
|
66
75
|
const res = await gwFetch('POST', '/logout', {
|
|
67
|
-
headers: await
|
|
76
|
+
headers: await authedHeaders(token),
|
|
68
77
|
body: JSON.stringify({ sessionId }),
|
|
69
78
|
});
|
|
70
79
|
if (!res.ok)
|
|
71
80
|
throw await errorFromResponse(res);
|
|
72
81
|
}
|
|
82
|
+
export async function gatewayLogoutAll(token) {
|
|
83
|
+
const res = await gwFetch('POST', '/logout-all', { headers: await authedHeaders(token) });
|
|
84
|
+
if (!res.ok)
|
|
85
|
+
throw await errorFromResponse(res);
|
|
86
|
+
}
|
|
73
87
|
export const gatewaySecurity = {
|
|
74
88
|
status: async (token) => {
|
|
75
89
|
const res = await gwFetch('GET', '/security/status', { headers: await authedHeaders(token) });
|
|
@@ -82,5 +96,6 @@ export const gatewaySecurity = {
|
|
|
82
96
|
challenge: async (token) => post('/security/challenge', {}, await authedHeaders(token)),
|
|
83
97
|
disable: async (token, challengeId, code, type) => post('/security/disable-2fa', { challengeId, code, type }, await authedHeaders(token)),
|
|
84
98
|
regenerateBackupCodes: async (token, challengeId, code, type) => post('/security/regenerate-backup-codes', { challengeId, code, type }, await authedHeaders(token)),
|
|
99
|
+
changePassword: async (token, currentPassword, newPassword) => post('/security/change-password', { currentPassword, newPassword }, await authedHeaders(token)),
|
|
85
100
|
};
|
|
86
101
|
//# sourceMappingURL=gateway-client.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gateway-client.js","sourceRoot":"","sources":["../../../src/lib/auth/gateway-client.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"gateway-client.js","sourceRoot":"","sources":["../../../src/lib/auth/gateway-client.ts"],"names":[],"mappings":"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"}
|