cauthy-auth 0.27.0 → 0.28.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/cli.js +3 -1
- package/dist/client.d.mts +12 -3
- package/dist/client.d.ts +12 -3
- package/dist/client.js +132 -17
- package/dist/client.js.map +1 -1
- package/dist/client.mjs +126 -16
- package/dist/client.mjs.map +1 -1
- package/dist/index.d.mts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.js +152 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +147 -20
- package/dist/index.mjs.map +1 -1
- package/dist/react.d.mts +27 -1
- package/dist/react.d.ts +27 -1
- package/dist/react.js +150 -23
- package/dist/react.js.map +1 -1
- package/dist/react.mjs +150 -23
- package/dist/react.mjs.map +1 -1
- package/dist/styles.css +6 -0
- package/dist/svelte.d.mts +1 -1
- package/dist/svelte.d.ts +1 -1
- package/dist/svelte.js +120 -15
- package/dist/svelte.js.map +1 -1
- package/dist/svelte.mjs +120 -15
- package/dist/svelte.mjs.map +1 -1
- package/dist/validate-sEXG82po.d.mts +66 -0
- package/dist/validate-sEXG82po.d.ts +66 -0
- package/dist/vue.d.mts +1 -1
- package/dist/vue.d.ts +1 -1
- package/dist/vue.js +120 -15
- package/dist/vue.js.map +1 -1
- package/dist/vue.mjs +120 -15
- package/dist/vue.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/validate-BTRit1O1.d.mts +0 -19
- package/dist/validate-BTRit1O1.d.ts +0 -19
package/dist/svelte.mjs
CHANGED
|
@@ -116,9 +116,113 @@ function fromWire(wire) {
|
|
|
116
116
|
}
|
|
117
117
|
|
|
118
118
|
// src/validate.ts
|
|
119
|
-
var MIN_PASSWORD =
|
|
120
|
-
var MAX_PASSWORD =
|
|
119
|
+
var MIN_PASSWORD = 12;
|
|
120
|
+
var MAX_PASSWORD = 128;
|
|
121
|
+
var FLOOR_PASSWORD = 8;
|
|
121
122
|
var MAX_NAME = 120;
|
|
123
|
+
var CLASSES = ["lowercase", "uppercase", "digit", "symbol"];
|
|
124
|
+
var DEFAULT_PASSWORD_POLICY = Object.freeze({ min: MIN_PASSWORD, max: MAX_PASSWORD, requires: [], min_classes: 0, reject_breached: false });
|
|
125
|
+
var int = (v, fallback) => typeof v === "number" && Number.isFinite(v) ? Math.trunc(v) : fallback;
|
|
126
|
+
function passwordPolicyOf(raw) {
|
|
127
|
+
const r = raw && typeof raw === "object" ? raw : {};
|
|
128
|
+
const min = Math.min(Math.max(int(r.min ?? r.min_length, MIN_PASSWORD) || MIN_PASSWORD, FLOOR_PASSWORD), MAX_PASSWORD);
|
|
129
|
+
const max = Math.max(Math.min(int(r.max ?? r.max_length, MAX_PASSWORD) || MAX_PASSWORD, MAX_PASSWORD), min);
|
|
130
|
+
const asked = Array.isArray(r.requires) ? r.requires : [];
|
|
131
|
+
return {
|
|
132
|
+
min,
|
|
133
|
+
max,
|
|
134
|
+
requires: CLASSES.filter((c) => asked.includes(c)),
|
|
135
|
+
min_classes: Math.min(Math.max(int(r.min_classes ?? r.minClasses, 0), 0), CLASSES.length),
|
|
136
|
+
reject_breached: (r.reject_breached ?? r.rejectBreached) === true
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function utf8Length(v) {
|
|
140
|
+
let n = 0;
|
|
141
|
+
for (const ch of v) {
|
|
142
|
+
const c = ch.codePointAt(0);
|
|
143
|
+
n += c < 128 ? 1 : c < 2048 ? 2 : c < 65536 ? 3 : 4;
|
|
144
|
+
}
|
|
145
|
+
return n;
|
|
146
|
+
}
|
|
147
|
+
function classesOf(v) {
|
|
148
|
+
const has = /* @__PURE__ */ new Set();
|
|
149
|
+
for (const ch of v) {
|
|
150
|
+
if (/\p{Ll}/u.test(ch)) has.add("lowercase");
|
|
151
|
+
else if (/\p{Lu}/u.test(ch)) has.add("uppercase");
|
|
152
|
+
else if (/\p{Nd}/u.test(ch)) has.add("digit");
|
|
153
|
+
else if (!/\p{L}/u.test(ch)) has.add("symbol");
|
|
154
|
+
}
|
|
155
|
+
return has;
|
|
156
|
+
}
|
|
157
|
+
function passwordProblems(value, policy = DEFAULT_PASSWORD_POLICY) {
|
|
158
|
+
const p = passwordPolicyOf(policy);
|
|
159
|
+
const out = [];
|
|
160
|
+
const length = utf8Length(value);
|
|
161
|
+
if (length < p.min) out.push("too_short");
|
|
162
|
+
if (length > p.max) out.push("too_long");
|
|
163
|
+
const has = classesOf(value);
|
|
164
|
+
for (const c of p.requires) if (!has.has(c)) out.push(`needs_${c}`);
|
|
165
|
+
if (p.min_classes > 0 && CLASSES.filter((c) => has.has(c)).length < p.min_classes) out.push("needs_classes");
|
|
166
|
+
return out;
|
|
167
|
+
}
|
|
168
|
+
var RULES = {
|
|
169
|
+
en: {
|
|
170
|
+
between: "Between {min} and {max} characters.",
|
|
171
|
+
requires: "Include {kinds}.",
|
|
172
|
+
and: "and",
|
|
173
|
+
classes: "Use at least {n} of these: lowercase letters, uppercase letters, digits, symbols.",
|
|
174
|
+
breached: "Passwords found in known data breaches are not accepted.",
|
|
175
|
+
kinds: { lowercase: "a lowercase letter", uppercase: "an uppercase letter", digit: "a digit", symbol: "a symbol" },
|
|
176
|
+
reasons: {
|
|
177
|
+
too_short: "Use at least {min} characters.",
|
|
178
|
+
too_long: "Use at most {max} characters.",
|
|
179
|
+
needs_lowercase: "Include a lowercase letter.",
|
|
180
|
+
needs_uppercase: "Include an uppercase letter.",
|
|
181
|
+
needs_digit: "Include a digit.",
|
|
182
|
+
needs_symbol: "Include a symbol.",
|
|
183
|
+
needs_classes: "Use at least {n} of these: lowercase letters, uppercase letters, digits, symbols.",
|
|
184
|
+
breached: "This password appears in a known data breach. Choose a different one."
|
|
185
|
+
}
|
|
186
|
+
},
|
|
187
|
+
es: {
|
|
188
|
+
between: "Entre {min} y {max} caracteres.",
|
|
189
|
+
requires: "Incluye {kinds}.",
|
|
190
|
+
and: "y",
|
|
191
|
+
classes: "Usa al menos {n} de estos tipos: min\xFAsculas, may\xFAsculas, n\xFAmeros, s\xEDmbolos.",
|
|
192
|
+
breached: "No se aceptan contrase\xF1as que aparecen en filtraciones de datos conocidas.",
|
|
193
|
+
kinds: { lowercase: "una min\xFAscula", uppercase: "una may\xFAscula", digit: "un n\xFAmero", symbol: "un s\xEDmbolo" },
|
|
194
|
+
reasons: {
|
|
195
|
+
too_short: "Usa al menos {min} caracteres.",
|
|
196
|
+
too_long: "Usa como m\xE1ximo {max} caracteres.",
|
|
197
|
+
needs_lowercase: "Incluye una min\xFAscula.",
|
|
198
|
+
needs_uppercase: "Incluye una may\xFAscula.",
|
|
199
|
+
needs_digit: "Incluye un n\xFAmero.",
|
|
200
|
+
needs_symbol: "Incluye un s\xEDmbolo.",
|
|
201
|
+
needs_classes: "Usa al menos {n} de estos tipos: min\xFAsculas, may\xFAsculas, n\xFAmeros, s\xEDmbolos.",
|
|
202
|
+
breached: "Esta contrase\xF1a aparece en una filtraci\xF3n de datos conocida. Elige otra."
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
var fill = (s, p) => s.replace("{min}", String(p.min)).replace("{max}", String(p.max)).replace("{n}", String(p.min_classes));
|
|
207
|
+
function describePasswordPolicy(policy = DEFAULT_PASSWORD_POLICY, locale = "en") {
|
|
208
|
+
const p = passwordPolicyOf(policy);
|
|
209
|
+
const t = RULES[locale] ?? RULES.en;
|
|
210
|
+
const parts = [fill(t.between, p)];
|
|
211
|
+
if (p.requires.length > 0) {
|
|
212
|
+
const kinds = p.requires.map((c) => t.kinds[c]);
|
|
213
|
+
const listed = kinds.length === 1 ? kinds[0] : `${kinds.slice(0, -1).join(", ")} ${t.and} ${kinds[kinds.length - 1]}`;
|
|
214
|
+
parts.push(t.requires.replace("{kinds}", listed));
|
|
215
|
+
}
|
|
216
|
+
if (p.min_classes > 0) parts.push(fill(t.classes, p));
|
|
217
|
+
if (p.reject_breached) parts.push(t.breached);
|
|
218
|
+
return parts.join(" ");
|
|
219
|
+
}
|
|
220
|
+
function explainPasswordProblems(reasons, policy = DEFAULT_PASSWORD_POLICY, locale = "en") {
|
|
221
|
+
const p = passwordPolicyOf(policy);
|
|
222
|
+
const t = RULES[locale] ?? RULES.en;
|
|
223
|
+
const said = reasons.filter((r) => r in t.reasons).map((r) => fill(t.reasons[r], p));
|
|
224
|
+
return said.length > 0 ? said.join(" ") : describePasswordPolicy(p, locale);
|
|
225
|
+
}
|
|
122
226
|
var EMAIL = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
123
227
|
function checkEmail(value) {
|
|
124
228
|
const v = typeof value === "string" ? value.trim() : "";
|
|
@@ -131,13 +235,12 @@ function checkPassword(value) {
|
|
|
131
235
|
if (value.length > MAX_PASSWORD) return { field: "password", code: "too_long", message: "That password is too long." };
|
|
132
236
|
return null;
|
|
133
237
|
}
|
|
134
|
-
function checkNewPassword(value) {
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
}
|
|
140
|
-
return null;
|
|
238
|
+
function checkNewPassword(value, policy) {
|
|
239
|
+
if (typeof value !== "string" || value === "") return { field: "password", code: "required", message: "Enter your password." };
|
|
240
|
+
const p = policy ? passwordPolicyOf(policy) : DEFAULT_PASSWORD_POLICY;
|
|
241
|
+
const reasons = passwordProblems(value, p);
|
|
242
|
+
if (reasons.length === 0) return null;
|
|
243
|
+
return { field: "password", code: reasons[0], message: explainPasswordProblems(reasons, p) };
|
|
141
244
|
}
|
|
142
245
|
function checkName(value) {
|
|
143
246
|
if (value === void 0 || value === null || value === "") return null;
|
|
@@ -200,7 +303,7 @@ function createAuthClient(options = {}) {
|
|
|
200
303
|
const body = await res.json().catch(() => null);
|
|
201
304
|
if (res.ok && body && typeof body.status === "string") return { ok: true, ...body };
|
|
202
305
|
const e = body?.error;
|
|
203
|
-
return { ok: false, error: e && typeof e.code === "string" ? { code: e.code, message: String(e.message ?? ""), ...e.field ? { field: e.field } : {} } : UNAVAILABLE };
|
|
306
|
+
return { ok: false, error: e && typeof e.code === "string" ? { code: e.code, message: String(e.message ?? ""), ...e.field ? { field: e.field } : {}, ...Array.isArray(e.reasons) ? { reasons: e.reasons.map(String) } : {} } : UNAVAILABLE };
|
|
204
307
|
} catch {
|
|
205
308
|
return { ok: false, error: UNAVAILABLE };
|
|
206
309
|
}
|
|
@@ -228,12 +331,14 @@ function createAuthClient(options = {}) {
|
|
|
228
331
|
if (o.locale) q.set("locale", o.locale);
|
|
229
332
|
return `${base}/login?${q}`;
|
|
230
333
|
};
|
|
334
|
+
let policy;
|
|
231
335
|
async function methods() {
|
|
232
336
|
try {
|
|
233
337
|
const res = await doFetch(`${base}/methods`, { credentials: "same-origin", headers: { accept: "application/json" } });
|
|
234
338
|
if (res.ok) {
|
|
235
339
|
const m = await res.json();
|
|
236
|
-
|
|
340
|
+
if (m.password) policy = passwordPolicyOf(m.password);
|
|
341
|
+
return { providers: [], signUp: true, magicLink: false, passkey: false, ...m, ...policy ? { password: policy } : {}, passkeyHere: m.passkeyHere === true, passkeyOnCauthy: m.passkeyOnCauthy ?? m.passkey === true, sso: m.sso === true };
|
|
237
342
|
}
|
|
238
343
|
} catch {
|
|
239
344
|
}
|
|
@@ -377,12 +482,12 @@ function createAuthClient(options = {}) {
|
|
|
377
482
|
email: (f) => post(
|
|
378
483
|
"/sign-up/email",
|
|
379
484
|
{ email: f.email, password: f.password, name: f.name, organization: f.organization, acceptLegal: f.acceptLegal, consents: f.consents },
|
|
380
|
-
firstProblem(checkName(f.name), checkEmail(f.email), checkNewPassword(f.password), checkOrganization(f.organization)),
|
|
485
|
+
firstProblem(checkName(f.name), checkEmail(f.email), checkNewPassword(f.password, policy), checkOrganization(f.organization)),
|
|
381
486
|
f.captchaToken
|
|
382
487
|
)
|
|
383
488
|
},
|
|
384
489
|
forgotPassword: (f) => post("/forgot-password", { email: f.email }, checkEmail(f.email), f.captchaToken),
|
|
385
|
-
resetPassword: (f) => post("/reset-password", { token: f.token, password: f.password }, checkNewPassword(f.password)),
|
|
490
|
+
resetPassword: (f) => post("/reset-password", { token: f.token, password: f.password }, checkNewPassword(f.password, policy)),
|
|
386
491
|
verifyEmail: (f) => post("/verify-email", { token: f.token }, null),
|
|
387
492
|
signOut: () => post("/sign-out", {}, null),
|
|
388
493
|
organizations: {
|
|
@@ -416,7 +521,7 @@ function createAuthClient(options = {}) {
|
|
|
416
521
|
},
|
|
417
522
|
acceptLegal: (f = {}) => post("/me/legal/accept", { kinds: f.kinds ?? [] }, null),
|
|
418
523
|
changePassword: (f) => {
|
|
419
|
-
const bad = checkNewPassword(f.newPassword);
|
|
524
|
+
const bad = checkNewPassword(f.newPassword, policy);
|
|
420
525
|
return post("/me/password", { password: f.password, newPassword: f.newPassword }, bad ? { ...bad, field: "newPassword" } : null);
|
|
421
526
|
},
|
|
422
527
|
mfa: {
|
|
@@ -447,7 +552,7 @@ function createAuthClient(options = {}) {
|
|
|
447
552
|
return body && Array.isArray(body.sessions) ? body.sessions : [];
|
|
448
553
|
},
|
|
449
554
|
signOutEverywhere: () => post("/me/sessions/end", {}, null),
|
|
450
|
-
upgrade: (f) => post("/me/upgrade", { email: f.email, password: f.password, name: f.name ?? "" }, firstProblem(checkName(f.name), checkEmail(f.email), checkNewPassword(f.password))),
|
|
555
|
+
upgrade: (f) => post("/me/upgrade", { email: f.email, password: f.password, name: f.name ?? "" }, firstProblem(checkName(f.name), checkEmail(f.email), checkNewPassword(f.password, policy))),
|
|
451
556
|
upgradeUrl,
|
|
452
557
|
upgradeWith(provider, o) {
|
|
453
558
|
window.location.assign(upgradeUrl(provider, o));
|