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/client.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;
|
|
@@ -308,7 +411,7 @@ function createAuthClient(options = {}) {
|
|
|
308
411
|
const body = await res.json().catch(() => null);
|
|
309
412
|
if (res.ok && body && typeof body.status === "string") return { ok: true, ...body };
|
|
310
413
|
const e = body?.error;
|
|
311
|
-
return { ok: false, error: e && typeof e.code === "string" ? { code: e.code, message: String(e.message ?? ""), ...e.field ? { field: e.field } : {} } : UNAVAILABLE };
|
|
414
|
+
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 };
|
|
312
415
|
} catch {
|
|
313
416
|
return { ok: false, error: UNAVAILABLE };
|
|
314
417
|
}
|
|
@@ -336,12 +439,14 @@ function createAuthClient(options = {}) {
|
|
|
336
439
|
if (o.locale) q.set("locale", o.locale);
|
|
337
440
|
return `${base}/login?${q}`;
|
|
338
441
|
};
|
|
442
|
+
let policy;
|
|
339
443
|
async function methods() {
|
|
340
444
|
try {
|
|
341
445
|
const res = await doFetch(`${base}/methods`, { credentials: "same-origin", headers: { accept: "application/json" } });
|
|
342
446
|
if (res.ok) {
|
|
343
447
|
const m = await res.json();
|
|
344
|
-
|
|
448
|
+
if (m.password) policy = passwordPolicyOf(m.password);
|
|
449
|
+
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 };
|
|
345
450
|
}
|
|
346
451
|
} catch {
|
|
347
452
|
}
|
|
@@ -485,12 +590,12 @@ function createAuthClient(options = {}) {
|
|
|
485
590
|
email: (f) => post(
|
|
486
591
|
"/sign-up/email",
|
|
487
592
|
{ email: f.email, password: f.password, name: f.name, organization: f.organization, acceptLegal: f.acceptLegal, consents: f.consents },
|
|
488
|
-
firstProblem(checkName(f.name), checkEmail(f.email), checkNewPassword(f.password), checkOrganization(f.organization)),
|
|
593
|
+
firstProblem(checkName(f.name), checkEmail(f.email), checkNewPassword(f.password, policy), checkOrganization(f.organization)),
|
|
489
594
|
f.captchaToken
|
|
490
595
|
)
|
|
491
596
|
},
|
|
492
597
|
forgotPassword: (f) => post("/forgot-password", { email: f.email }, checkEmail(f.email), f.captchaToken),
|
|
493
|
-
resetPassword: (f) => post("/reset-password", { token: f.token, password: f.password }, checkNewPassword(f.password)),
|
|
598
|
+
resetPassword: (f) => post("/reset-password", { token: f.token, password: f.password }, checkNewPassword(f.password, policy)),
|
|
494
599
|
verifyEmail: (f) => post("/verify-email", { token: f.token }, null),
|
|
495
600
|
signOut: () => post("/sign-out", {}, null),
|
|
496
601
|
organizations: {
|
|
@@ -524,7 +629,7 @@ function createAuthClient(options = {}) {
|
|
|
524
629
|
},
|
|
525
630
|
acceptLegal: (f = {}) => post("/me/legal/accept", { kinds: f.kinds ?? [] }, null),
|
|
526
631
|
changePassword: (f) => {
|
|
527
|
-
const bad = checkNewPassword(f.newPassword);
|
|
632
|
+
const bad = checkNewPassword(f.newPassword, policy);
|
|
528
633
|
return post("/me/password", { password: f.password, newPassword: f.newPassword }, bad ? { ...bad, field: "newPassword" } : null);
|
|
529
634
|
},
|
|
530
635
|
mfa: {
|
|
@@ -555,7 +660,7 @@ function createAuthClient(options = {}) {
|
|
|
555
660
|
return body && Array.isArray(body.sessions) ? body.sessions : [];
|
|
556
661
|
},
|
|
557
662
|
signOutEverywhere: () => post("/me/sessions/end", {}, null),
|
|
558
|
-
upgrade: (f) => post("/me/upgrade", { email: f.email, password: f.password, name: f.name ?? "" }, firstProblem(checkName(f.name), checkEmail(f.email), checkNewPassword(f.password))),
|
|
663
|
+
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))),
|
|
559
664
|
upgradeUrl,
|
|
560
665
|
upgradeWith(provider, o) {
|
|
561
666
|
window.location.assign(upgradeUrl(provider, o));
|
|
@@ -592,6 +697,7 @@ function createAuthClient(options = {}) {
|
|
|
592
697
|
};
|
|
593
698
|
}
|
|
594
699
|
export {
|
|
700
|
+
DEFAULT_PASSWORD_POLICY,
|
|
595
701
|
MIN_PASSWORD,
|
|
596
702
|
canAutofillPasskeys,
|
|
597
703
|
canUsePasskeys,
|
|
@@ -601,6 +707,10 @@ export {
|
|
|
601
707
|
checkNewPassword,
|
|
602
708
|
checkPassword,
|
|
603
709
|
createAuthClient,
|
|
604
|
-
createSessionStore
|
|
710
|
+
createSessionStore,
|
|
711
|
+
describePasswordPolicy,
|
|
712
|
+
explainPasswordProblems,
|
|
713
|
+
passwordPolicyOf,
|
|
714
|
+
passwordProblems
|
|
605
715
|
};
|
|
606
716
|
//# sourceMappingURL=client.mjs.map
|