@mostajs/auth 3.0.2 → 3.1.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/lib/anon-token.d.ts +40 -0
- package/dist/lib/anon-token.js +69 -0
- package/package.json +6 -1
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Génère un nouveau token anonyme — 32 caractères hexadécimaux issus de
|
|
3
|
+
* 16 bytes de `randomBytes` (CSPRNG).
|
|
4
|
+
*/
|
|
5
|
+
export declare function generateAnonToken(): string;
|
|
6
|
+
/**
|
|
7
|
+
* Formate un email synthétique stable pour un token + un scope.
|
|
8
|
+
* Le scope évite qu'un même token "fuite" inter-projets *(domaine
|
|
9
|
+
* différent → email différent → respondent distinct par projet)*.
|
|
10
|
+
*
|
|
11
|
+
* Le résultat est non-routable (`.anon.local`) — pas de risque
|
|
12
|
+
* d'envoi mail par accident.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* anonEmail('a1b2c3d4e5f6', 'survey-2026')
|
|
16
|
+
* → 'anon-a1b2c3d4e5f6@survey-2026.anon.local'
|
|
17
|
+
*/
|
|
18
|
+
export declare function anonEmail(token: string, scope: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Vrai si l'email donné a la forme générée par `anonEmail` — utile
|
|
21
|
+
* pour repérer les respondents anonymes dans les dashboards / exports
|
|
22
|
+
* sans avoir à stocker un flag séparé *(quoique le flag reste une
|
|
23
|
+
* bonne pratique pour la requête DB)*.
|
|
24
|
+
*/
|
|
25
|
+
export declare function isAnonEmail(email: string | null | undefined): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* Convention de nom du cookie à utiliser. Le consumer reste libre de
|
|
28
|
+
* choisir le sien, mais cette constante factorise la pratique courante.
|
|
29
|
+
*/
|
|
30
|
+
export declare const ANON_COOKIE_DEFAULT_NAME = "anon_tk";
|
|
31
|
+
/**
|
|
32
|
+
* Options de cookie recommandées (utilisées par les implémentations
|
|
33
|
+
* Next/Express). Le consumer applique celles-ci à son cookie store.
|
|
34
|
+
*/
|
|
35
|
+
export declare const ANON_COOKIE_DEFAULT_OPTIONS: {
|
|
36
|
+
httpOnly: boolean;
|
|
37
|
+
sameSite: "lax";
|
|
38
|
+
path: string;
|
|
39
|
+
maxAge: number;
|
|
40
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// @mostajs/auth — Anonymous token primitives — v3.1.0+
|
|
2
|
+
// Author: Dr Hamid MADANI <drmdh@msn.com>
|
|
3
|
+
//
|
|
4
|
+
// Pour les questionnaires / pages publiques `visibility=public-anon` qui
|
|
5
|
+
// veulent retrouver les réponses entre sessions sans demander d'email.
|
|
6
|
+
// Le module fournit uniquement les **primitives** : génération d'un token
|
|
7
|
+
// aléatoire et formatage d'un email synthétique stable. Le **stockage du
|
|
8
|
+
// cookie** est laissé au consumer car la signature dépend du framework
|
|
9
|
+
// (Next.js `cookies()`, Express `res.cookie()`, etc.).
|
|
10
|
+
//
|
|
11
|
+
// Design clé :
|
|
12
|
+
// - 16 bytes de hasard cryptographique → 32 chars hex. Suffisant contre
|
|
13
|
+
// la collision (probabilité < 2⁻⁶⁴ pour 10⁹ tokens).
|
|
14
|
+
// - Email synthétique de la forme `anon-<token12>@<scope>.anon.local` :
|
|
15
|
+
// stable, reconnaissable comme anon dans les exports / dashboards,
|
|
16
|
+
// non-routable (TLD `.local` réservé) → impossible d'envoyer un mail
|
|
17
|
+
// dessus par accident.
|
|
18
|
+
// - Aucune dépendance externe — uniquement `node:crypto`.
|
|
19
|
+
import { randomBytes } from 'node:crypto';
|
|
20
|
+
/**
|
|
21
|
+
* Génère un nouveau token anonyme — 32 caractères hexadécimaux issus de
|
|
22
|
+
* 16 bytes de `randomBytes` (CSPRNG).
|
|
23
|
+
*/
|
|
24
|
+
export function generateAnonToken() {
|
|
25
|
+
return randomBytes(16).toString('hex');
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Formate un email synthétique stable pour un token + un scope.
|
|
29
|
+
* Le scope évite qu'un même token "fuite" inter-projets *(domaine
|
|
30
|
+
* différent → email différent → respondent distinct par projet)*.
|
|
31
|
+
*
|
|
32
|
+
* Le résultat est non-routable (`.anon.local`) — pas de risque
|
|
33
|
+
* d'envoi mail par accident.
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* anonEmail('a1b2c3d4e5f6', 'survey-2026')
|
|
37
|
+
* → 'anon-a1b2c3d4e5f6@survey-2026.anon.local'
|
|
38
|
+
*/
|
|
39
|
+
export function anonEmail(token, scope) {
|
|
40
|
+
const t = String(token ?? '').slice(0, 12);
|
|
41
|
+
const s = String(scope ?? 'default').toLowerCase().replace(/[^a-z0-9-]+/g, '-');
|
|
42
|
+
return `anon-${t}@${s}.anon.local`;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Vrai si l'email donné a la forme générée par `anonEmail` — utile
|
|
46
|
+
* pour repérer les respondents anonymes dans les dashboards / exports
|
|
47
|
+
* sans avoir à stocker un flag séparé *(quoique le flag reste une
|
|
48
|
+
* bonne pratique pour la requête DB)*.
|
|
49
|
+
*/
|
|
50
|
+
export function isAnonEmail(email) {
|
|
51
|
+
if (!email)
|
|
52
|
+
return false;
|
|
53
|
+
return /^anon-[a-f0-9]{12}@[a-z0-9-]+\.anon\.local$/.test(email);
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Convention de nom du cookie à utiliser. Le consumer reste libre de
|
|
57
|
+
* choisir le sien, mais cette constante factorise la pratique courante.
|
|
58
|
+
*/
|
|
59
|
+
export const ANON_COOKIE_DEFAULT_NAME = 'anon_tk';
|
|
60
|
+
/**
|
|
61
|
+
* Options de cookie recommandées (utilisées par les implémentations
|
|
62
|
+
* Next/Express). Le consumer applique celles-ci à son cookie store.
|
|
63
|
+
*/
|
|
64
|
+
export const ANON_COOKIE_DEFAULT_OPTIONS = {
|
|
65
|
+
httpOnly: true,
|
|
66
|
+
sameSite: 'lax',
|
|
67
|
+
path: '/',
|
|
68
|
+
maxAge: 60 * 60 * 24 * 365, // 1 an
|
|
69
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mostajs/auth",
|
|
3
|
-
"version": "3.0
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "Authentication — complete: email/password (Argon2id) + OAuth + magic link + MFA TOTP + WebAuthn/Passkeys + RGPD lifecycle + device_flow/pkce events + accountId propagation server↔client",
|
|
5
5
|
"author": "Dr Hamid MADANI <drmdh@msn.com>",
|
|
6
6
|
"license": "AGPL-3.0-or-later",
|
|
@@ -113,6 +113,11 @@
|
|
|
113
113
|
"import": "./dist/lib/magic-link.js",
|
|
114
114
|
"default": "./dist/lib/magic-link.js"
|
|
115
115
|
},
|
|
116
|
+
"./lib/anon-token": {
|
|
117
|
+
"types": "./dist/lib/anon-token.d.ts",
|
|
118
|
+
"import": "./dist/lib/anon-token.js",
|
|
119
|
+
"default": "./dist/lib/anon-token.js"
|
|
120
|
+
},
|
|
116
121
|
"./lib/mfa-totp": {
|
|
117
122
|
"types": "./dist/lib/mfa-totp.d.ts",
|
|
118
123
|
"import": "./dist/lib/mfa-totp.js",
|