@seifer-webapp-factory/authentication 0.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/README.md +8 -0
- package/backend/templates/config/config-fragment.ts +73 -0
- package/backend/templates/mail/templates.ts +84 -0
- package/backend/templates/nestjs/auth.controller.ts +274 -0
- package/backend/templates/nestjs/auth.module.ts +207 -0
- package/backend/templates/nestjs/tokens.ts +24 -0
- package/backend/templates/persistence/migrations/0001_auth.sql +36 -0
- package/backend/templates/persistence/migrations/index.ts +75 -0
- package/backend/templates/persistence/pg-single-use-store.ts +64 -0
- package/backend/templates/persistence/pg-token-store.ts +75 -0
- package/backend/templates/persistence/pg-user-store.ts +53 -0
- package/backend/templates/security/cookies.ts +89 -0
- package/backend/templates/security/csrf.ts +44 -0
- package/backend/templates/security/headers.ts +30 -0
- package/backend/templates/security/redaction.ts +38 -0
- package/dist/backend/src/errors.d.ts +12 -0
- package/dist/backend/src/errors.d.ts.map +1 -0
- package/dist/backend/src/errors.js +55 -0
- package/dist/backend/src/errors.js.map +1 -0
- package/dist/backend/src/index.d.ts +9 -0
- package/dist/backend/src/index.d.ts.map +1 -0
- package/dist/backend/src/index.js +8 -0
- package/dist/backend/src/index.js.map +1 -0
- package/dist/backend/src/ports.d.ts +60 -0
- package/dist/backend/src/ports.d.ts.map +1 -0
- package/dist/backend/src/ports.js +2 -0
- package/dist/backend/src/ports.js.map +1 -0
- package/dist/backend/src/services.d.ts +49 -0
- package/dist/backend/src/services.d.ts.map +1 -0
- package/dist/backend/src/services.js +178 -0
- package/dist/backend/src/services.js.map +1 -0
- package/dist/contract/endpoints.d.ts +259 -0
- package/dist/contract/endpoints.d.ts.map +1 -0
- package/dist/contract/endpoints.js +42 -0
- package/dist/contract/endpoints.js.map +1 -0
- package/dist/contract/errors.d.ts +23 -0
- package/dist/contract/errors.d.ts.map +1 -0
- package/dist/contract/errors.js +31 -0
- package/dist/contract/errors.js.map +1 -0
- package/dist/contract/events.d.ts +40 -0
- package/dist/contract/events.d.ts.map +1 -0
- package/dist/contract/events.js +14 -0
- package/dist/contract/events.js.map +1 -0
- package/dist/contract/index.d.ts +9 -0
- package/dist/contract/index.d.ts.map +1 -0
- package/dist/contract/index.js +9 -0
- package/dist/contract/index.js.map +1 -0
- package/dist/contract/schemas.d.ts +150 -0
- package/dist/contract/schemas.d.ts.map +1 -0
- package/dist/contract/schemas.js +43 -0
- package/dist/contract/schemas.js.map +1 -0
- package/dist/frontend/src/client.d.ts +38 -0
- package/dist/frontend/src/client.d.ts.map +1 -0
- package/dist/frontend/src/client.js +88 -0
- package/dist/frontend/src/client.js.map +1 -0
- package/dist/frontend/src/composables.d.ts +46 -0
- package/dist/frontend/src/composables.d.ts.map +1 -0
- package/dist/frontend/src/composables.js +111 -0
- package/dist/frontend/src/composables.js.map +1 -0
- package/dist/frontend/src/guards.d.ts +10 -0
- package/dist/frontend/src/guards.d.ts.map +1 -0
- package/dist/frontend/src/guards.js +9 -0
- package/dist/frontend/src/guards.js.map +1 -0
- package/dist/frontend/src/index.d.ts +12 -0
- package/dist/frontend/src/index.d.ts.map +1 -0
- package/dist/frontend/src/index.js +9 -0
- package/dist/frontend/src/index.js.map +1 -0
- package/dist/manifest.d.ts +80 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +126 -0
- package/dist/manifest.js.map +1 -0
- package/dist/scaffolder/core/config.d.ts +213 -0
- package/dist/scaffolder/core/config.d.ts.map +1 -0
- package/dist/scaffolder/core/config.js +132 -0
- package/dist/scaffolder/core/config.js.map +1 -0
- package/dist/scaffolder/core/errors.d.ts +37 -0
- package/dist/scaffolder/core/errors.d.ts.map +1 -0
- package/dist/scaffolder/core/errors.js +46 -0
- package/dist/scaffolder/core/errors.js.map +1 -0
- package/dist/scaffolder/core/extend.d.ts +115 -0
- package/dist/scaffolder/core/extend.d.ts.map +1 -0
- package/dist/scaffolder/core/extend.js +116 -0
- package/dist/scaffolder/core/extend.js.map +1 -0
- package/dist/scaffolder/core/materialize.d.ts +71 -0
- package/dist/scaffolder/core/materialize.d.ts.map +1 -0
- package/dist/scaffolder/core/materialize.js +47 -0
- package/dist/scaffolder/core/materialize.js.map +1 -0
- package/dist/scaffolder/core/ports.d.ts +39 -0
- package/dist/scaffolder/core/ports.d.ts.map +1 -0
- package/dist/scaffolder/core/ports.js +33 -0
- package/dist/scaffolder/core/ports.js.map +1 -0
- package/dist/scaffolder/core/three-way-merge.d.ts +113 -0
- package/dist/scaffolder/core/three-way-merge.d.ts.map +1 -0
- package/dist/scaffolder/core/three-way-merge.js +184 -0
- package/dist/scaffolder/core/three-way-merge.js.map +1 -0
- package/dist/scaffolder/index.d.ts +21 -0
- package/dist/scaffolder/index.d.ts.map +1 -0
- package/dist/scaffolder/index.js +20 -0
- package/dist/scaffolder/index.js.map +1 -0
- package/frontend/templates/components/AuthField.vue +68 -0
- package/frontend/templates/i18n/en.json +70 -0
- package/frontend/templates/i18n/nl.json +70 -0
- package/frontend/templates/middleware/auth.ts +25 -0
- package/frontend/templates/middleware/guest.ts +25 -0
- package/frontend/templates/pages/forgot-password.vue +89 -0
- package/frontend/templates/pages/login.vue +90 -0
- package/frontend/templates/pages/logout.vue +46 -0
- package/frontend/templates/pages/register.vue +100 -0
- package/frontend/templates/pages/reset-password.vue +105 -0
- package/frontend/templates/pages/verify-email.vue +76 -0
- package/frontend/templates/plugins/auth.client.ts +111 -0
- package/frontend/templates/runtime.ts +60 -0
- package/package.json +71 -0
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* three-way-merge — de UPGRADE-stap die "mag divergeren" van een val naar een feature maakt (US-A0804).
|
|
3
|
+
*
|
|
4
|
+
* Per surface-bestand reconcilieert `mergeSurface` drie versies:
|
|
5
|
+
* - `base` = de oorspronkelijk gematerialiseerde template (uit het `MaterializationRecord`),
|
|
6
|
+
* - `upstream` = de nieuwe template-versie,
|
|
7
|
+
* - `current` = het (mogelijk gedivergeerde) projectbestand.
|
|
8
|
+
*
|
|
9
|
+
* Regels:
|
|
10
|
+
* - `current === base` → schoon toepassen: neem `upstream` over (project onaangeroerd).
|
|
11
|
+
* - `upstream === base` → behoud `current` (upstream ongewijzigd; divergentie blijft staan).
|
|
12
|
+
* - `current === upstream` → beide al gelijk; niets te doen.
|
|
13
|
+
* - anders → regel-gebaseerde diff3: niet-botsende wijzigingen mergen, botsende
|
|
14
|
+
* krijgen CONFLICT-markers (nooit stil overschrijven).
|
|
15
|
+
*
|
|
16
|
+
* `upgradeSurface` orkestreert dit over alle bestanden met behulp van het `MaterializationRecord` en
|
|
17
|
+
* de twee templateVersions. Puur & deterministisch: geen fs-side-effects in de merge zelf, geen random.
|
|
18
|
+
*/
|
|
19
|
+
import type { AuthScaffolderFsPort, FileDescriptor } from './ports.js';
|
|
20
|
+
import type { MaterializationRecord } from './materialize.js';
|
|
21
|
+
/** De uitkomst-categorie van een merge. */
|
|
22
|
+
export type MergeStatus = 'clean' | 'unchanged' | 'merged' | 'conflict';
|
|
23
|
+
/** Labels die in de conflict-markers verschijnen. */
|
|
24
|
+
export interface MergeMarkerLabels {
|
|
25
|
+
readonly current: string;
|
|
26
|
+
readonly base: string;
|
|
27
|
+
readonly upstream: string;
|
|
28
|
+
}
|
|
29
|
+
/** Invoer voor één bestand-merge. */
|
|
30
|
+
export interface MergeInput {
|
|
31
|
+
readonly base: string;
|
|
32
|
+
readonly upstream: string;
|
|
33
|
+
readonly current: string;
|
|
34
|
+
readonly labels?: MergeMarkerLabels;
|
|
35
|
+
}
|
|
36
|
+
/** Resultaat van één bestand-merge. */
|
|
37
|
+
export interface MergeResult {
|
|
38
|
+
readonly status: MergeStatus;
|
|
39
|
+
/** De uiteindelijke inhoud (met conflict-markers als `status === 'conflict'`). */
|
|
40
|
+
readonly contents: string;
|
|
41
|
+
/** True als er minstens één conflict-hunk in zit. */
|
|
42
|
+
readonly conflict: boolean;
|
|
43
|
+
/** Aantal conflict-hunks (0 als schoon). */
|
|
44
|
+
readonly conflicts: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Reconcilieert één bestand (base ↔ upstream ↔ current). Zie de bestandskop voor de regels.
|
|
48
|
+
*/
|
|
49
|
+
export declare function mergeSurface(input: MergeInput): MergeResult;
|
|
50
|
+
/** De uitkomst per bestand binnen een upgrade. */
|
|
51
|
+
export interface FileUpgradeOutcome {
|
|
52
|
+
readonly path: string;
|
|
53
|
+
/** Merge-status, of 'added' voor een nieuw upstream-bestand dat nog niet in het project stond. */
|
|
54
|
+
readonly status: MergeStatus | 'added';
|
|
55
|
+
readonly contents: string;
|
|
56
|
+
readonly conflict: boolean;
|
|
57
|
+
}
|
|
58
|
+
/** Uitkomst van een acceptatiegate (contract-tests + verticale e2e). */
|
|
59
|
+
export interface GateOutcome {
|
|
60
|
+
readonly ok: boolean;
|
|
61
|
+
/** Naam van de gefaalde gate (bv. 'contract' of 'e2e'), indien van toepassing. */
|
|
62
|
+
readonly failed?: string;
|
|
63
|
+
}
|
|
64
|
+
/** Een acceptatiegate-callback die na de merge draait; ontvangt de voorgestelde bestanden. */
|
|
65
|
+
export type AcceptanceGate = (files: readonly FileUpgradeOutcome[]) => GateOutcome;
|
|
66
|
+
/** Opties voor `upgradeSurface`. */
|
|
67
|
+
export interface UpgradeOptions {
|
|
68
|
+
/** Het stempelrecord van de vorige materialisatie (levert base + fromVersion per bestand). */
|
|
69
|
+
readonly record: MaterializationRecord;
|
|
70
|
+
/** De nieuwe surface-templates (upstream), voor de doel-`toVersion`. */
|
|
71
|
+
readonly upstreamFiles: readonly FileDescriptor[];
|
|
72
|
+
/** De doel-templateVersion die na een veilige upgrade gestempeld wordt. */
|
|
73
|
+
readonly toVersion: string;
|
|
74
|
+
/** Fs-port om de huidige (mogelijk gedivergeerde) projectbestanden in te lezen. */
|
|
75
|
+
readonly fsPort: AuthScaffolderFsPort;
|
|
76
|
+
/**
|
|
77
|
+
* Schrijf de gemergede inhoud terug via de fs-port. Standaard `false` (droog: alleen een plan).
|
|
78
|
+
* Conflict-bestanden worden NOOIT geschreven, ook niet met `write: true` — ze wachten op reconciliatie.
|
|
79
|
+
*/
|
|
80
|
+
readonly write?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Optionele acceptatiegate (contract + e2e). Wordt hij opgegeven én slaagt hij niet, dan is de
|
|
83
|
+
* upgrade niet veilig (US-A0804 AC3 / US-A1004 AC3): bewuste overschrijding richting fork (niveau 4).
|
|
84
|
+
*/
|
|
85
|
+
readonly gate?: AcceptanceGate;
|
|
86
|
+
readonly labels?: MergeMarkerLabels;
|
|
87
|
+
}
|
|
88
|
+
/** Uitkomst van een volledige upgrade-run. */
|
|
89
|
+
export interface UpgradeResult {
|
|
90
|
+
readonly fromVersion: string;
|
|
91
|
+
readonly toVersion: string;
|
|
92
|
+
readonly files: readonly FileUpgradeOutcome[];
|
|
93
|
+
/** Paden met een onopgelost conflict. */
|
|
94
|
+
readonly conflicts: readonly string[];
|
|
95
|
+
/**
|
|
96
|
+
* Is de upgrade veilig? True als er geen conflicten zijn ÉN (indien opgegeven) de gate groen is.
|
|
97
|
+
* Bij `false` is de divergentie bewust richting niveau 4 (fork) gegaan tenzij eerst gereconcilieerd.
|
|
98
|
+
*/
|
|
99
|
+
readonly safe: boolean;
|
|
100
|
+
/** Uitkomst van de gate, indien er één is opgegeven. */
|
|
101
|
+
readonly gate?: GateOutcome;
|
|
102
|
+
/**
|
|
103
|
+
* Het bijgewerkte stempelrecord: schoon-toegepaste/gemergede bestanden staan op `toVersion` met de
|
|
104
|
+
* nieuwe basis; conflict-bestanden houden hun oude stempel tot ze gereconcilieerd zijn.
|
|
105
|
+
*/
|
|
106
|
+
readonly record: MaterializationRecord;
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Orkestreert de upgrade over alle upstream-bestanden op basis van het stempelrecord.
|
|
110
|
+
* Mecht uitsluitend de surface; het mechanisme upgradet los via semver (buiten deze functie).
|
|
111
|
+
*/
|
|
112
|
+
export declare function upgradeSurface(options: UpgradeOptions): UpgradeResult;
|
|
113
|
+
//# sourceMappingURL=three-way-merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"three-way-merge.d.ts","sourceRoot":"","sources":["../../../scaffolder/core/three-way-merge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
const DEFAULT_LABELS = { current: 'current', base: 'base', upstream: 'upstream' };
|
|
2
|
+
/**
|
|
3
|
+
* Reconcilieert één bestand (base ↔ upstream ↔ current). Zie de bestandskop voor de regels.
|
|
4
|
+
*/
|
|
5
|
+
export function mergeSurface(input) {
|
|
6
|
+
const { base, upstream, current } = input;
|
|
7
|
+
const labels = input.labels ?? DEFAULT_LABELS;
|
|
8
|
+
// Snelle, exacte gevallen — behandeld vóór de regel-diff zodat triviale upgrades geen merge doen.
|
|
9
|
+
if (current === base) {
|
|
10
|
+
// Project heeft niets aangeraakt → neem de nieuwe template schoon over.
|
|
11
|
+
return { status: 'clean', contents: upstream, conflict: false, conflicts: 0 };
|
|
12
|
+
}
|
|
13
|
+
if (upstream === base) {
|
|
14
|
+
// Upstream is onveranderd → behoud de (gedivergeerde) projectversie.
|
|
15
|
+
return { status: 'unchanged', contents: current, conflict: false, conflicts: 0 };
|
|
16
|
+
}
|
|
17
|
+
if (current === upstream) {
|
|
18
|
+
// Beide kanten kwamen op dezelfde inhoud uit → niets te mergen.
|
|
19
|
+
return { status: 'clean', contents: current, conflict: false, conflicts: 0 };
|
|
20
|
+
}
|
|
21
|
+
// Echte drie-weg-merge op regelniveau.
|
|
22
|
+
const { lines, conflicts } = threeWayMergeLines(splitLines(base), splitLines(current), splitLines(upstream), labels);
|
|
23
|
+
const contents = lines.join('\n');
|
|
24
|
+
return {
|
|
25
|
+
status: conflicts > 0 ? 'conflict' : 'merged',
|
|
26
|
+
contents,
|
|
27
|
+
conflict: conflicts > 0,
|
|
28
|
+
conflicts,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** Splitst inhoud in regels. Behoudt lege staart-regels zodat join('\n') exact terugkeert. */
|
|
32
|
+
function splitLines(text) {
|
|
33
|
+
return text.split('\n');
|
|
34
|
+
}
|
|
35
|
+
/** Array-gelijkheid op regels. */
|
|
36
|
+
function equalLines(a, b) {
|
|
37
|
+
if (a.length !== b.length)
|
|
38
|
+
return false;
|
|
39
|
+
for (let i = 0; i < a.length; i++) {
|
|
40
|
+
if (a[i] !== b[i])
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Longest common subsequence van twee regel-arrays. Levert de gematchte index-paren [xIdx, yIdx] in
|
|
47
|
+
* oplopende volgorde. Klassieke DP; deterministisch (bij gelijke lengte kiest hij consequent x++).
|
|
48
|
+
*/
|
|
49
|
+
function lcsPairs(x, y) {
|
|
50
|
+
const n = x.length;
|
|
51
|
+
const m = y.length;
|
|
52
|
+
const dp = Array.from({ length: n + 1 }, () => new Array(m + 1).fill(0));
|
|
53
|
+
for (let i = n - 1; i >= 0; i--) {
|
|
54
|
+
for (let j = m - 1; j >= 0; j--) {
|
|
55
|
+
dp[i][j] = x[i] === y[j] ? dp[i + 1][j + 1] + 1 : Math.max(dp[i + 1][j], dp[i][j + 1]);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const pairs = [];
|
|
59
|
+
let i = 0;
|
|
60
|
+
let j = 0;
|
|
61
|
+
while (i < n && j < m) {
|
|
62
|
+
if (x[i] === y[j]) {
|
|
63
|
+
pairs.push([i, j]);
|
|
64
|
+
i++;
|
|
65
|
+
j++;
|
|
66
|
+
}
|
|
67
|
+
else if (dp[i + 1][j] >= dp[i][j + 1]) {
|
|
68
|
+
i++;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
j++;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return pairs;
|
|
75
|
+
}
|
|
76
|
+
/** Zet LCS-paren om naar een map baseIndex → otherIndex. */
|
|
77
|
+
function matchMap(pairs) {
|
|
78
|
+
const map = new Map();
|
|
79
|
+
for (const [o, other] of pairs)
|
|
80
|
+
map.set(o, other);
|
|
81
|
+
return map;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* De eigenlijke diff3. Ankers = base-regels die ONgewijzigd zijn in zowel `current` als `upstream`
|
|
85
|
+
* (aanwezig in beide LCS'en). Tussen opeenvolgende ankers classificeren we het segment:
|
|
86
|
+
* - alleen upstream wijzigde → neem upstream-segment,
|
|
87
|
+
* - alleen current wijzigde → neem current-segment,
|
|
88
|
+
* - beide identiek gewijzigd → neem dat (geen conflict),
|
|
89
|
+
* - beide verschillend → CONFLICT-markers.
|
|
90
|
+
* Omdat beide LCS'en monotoon zijn in de base-index, zijn de ankers monotoon in alle drie de indices.
|
|
91
|
+
*/
|
|
92
|
+
function threeWayMergeLines(base, current, upstream, labels) {
|
|
93
|
+
const matchCurrent = matchMap(lcsPairs(base, current)); // baseIdx → currentIdx
|
|
94
|
+
const matchUpstream = matchMap(lcsPairs(base, upstream)); // baseIdx → upstreamIdx
|
|
95
|
+
const anchors = [];
|
|
96
|
+
for (let o = 0; o < base.length; o++) {
|
|
97
|
+
const a = matchCurrent.get(o);
|
|
98
|
+
const b = matchUpstream.get(o);
|
|
99
|
+
if (a !== undefined && b !== undefined)
|
|
100
|
+
anchors.push({ o, a, b });
|
|
101
|
+
}
|
|
102
|
+
const out = [];
|
|
103
|
+
let conflicts = 0;
|
|
104
|
+
let po = -1;
|
|
105
|
+
let pa = -1;
|
|
106
|
+
let pb = -1;
|
|
107
|
+
const emitSegment = (oE, aE, bE) => {
|
|
108
|
+
const baseSeg = base.slice(po + 1, oE);
|
|
109
|
+
const currentSeg = current.slice(pa + 1, aE);
|
|
110
|
+
const upstreamSeg = upstream.slice(pb + 1, bE);
|
|
111
|
+
if (baseSeg.length === 0 && currentSeg.length === 0 && upstreamSeg.length === 0)
|
|
112
|
+
return;
|
|
113
|
+
if (equalLines(currentSeg, baseSeg)) {
|
|
114
|
+
out.push(...upstreamSeg); // alleen upstream wijzigde
|
|
115
|
+
}
|
|
116
|
+
else if (equalLines(upstreamSeg, baseSeg)) {
|
|
117
|
+
out.push(...currentSeg); // alleen current wijzigde
|
|
118
|
+
}
|
|
119
|
+
else if (equalLines(currentSeg, upstreamSeg)) {
|
|
120
|
+
out.push(...currentSeg); // beide dezelfde wijziging
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
conflicts++;
|
|
124
|
+
out.push(`<<<<<<< ${labels.current}`, ...currentSeg, `||||||| ${labels.base}`, ...baseSeg, '=======', ...upstreamSeg, `>>>>>>> ${labels.upstream}`);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
for (const anchor of anchors) {
|
|
128
|
+
emitSegment(anchor.o, anchor.a, anchor.b);
|
|
129
|
+
out.push(base[anchor.o]); // het anker zelf is in alle drie identiek
|
|
130
|
+
po = anchor.o;
|
|
131
|
+
pa = anchor.a;
|
|
132
|
+
pb = anchor.b;
|
|
133
|
+
}
|
|
134
|
+
// Staart-segment na het laatste anker.
|
|
135
|
+
emitSegment(base.length, current.length, upstream.length);
|
|
136
|
+
return { lines: out, conflicts };
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Orkestreert de upgrade over alle upstream-bestanden op basis van het stempelrecord.
|
|
140
|
+
* Mecht uitsluitend de surface; het mechanisme upgradet los via semver (buiten deze functie).
|
|
141
|
+
*/
|
|
142
|
+
export function upgradeSurface(options) {
|
|
143
|
+
const { record, upstreamFiles, toVersion, fsPort, write = false, gate, labels } = options;
|
|
144
|
+
const fromVersion = record.templateVersion;
|
|
145
|
+
const files = [];
|
|
146
|
+
const conflicts = [];
|
|
147
|
+
const nextFiles = { ...record.files };
|
|
148
|
+
for (const upstream of upstreamFiles) {
|
|
149
|
+
const stamped = record.files[upstream.path];
|
|
150
|
+
const exists = fsPort.exists(upstream.path);
|
|
151
|
+
// Nieuw upstream-bestand (nog niet gematerialiseerd) of ontbrekend in het project → toevoegen.
|
|
152
|
+
if (stamped === undefined || !exists) {
|
|
153
|
+
files.push({ path: upstream.path, status: 'added', contents: upstream.contents, conflict: false });
|
|
154
|
+
if (write)
|
|
155
|
+
fsPort.write(upstream.path, upstream.contents);
|
|
156
|
+
nextFiles[upstream.path] = { templateVersion: toVersion, base: upstream.contents };
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
const current = fsPort.read(upstream.path);
|
|
160
|
+
const merge = mergeSurface({ base: stamped.base, upstream: upstream.contents, current, labels });
|
|
161
|
+
files.push({ path: upstream.path, status: merge.status, contents: merge.contents, conflict: merge.conflict });
|
|
162
|
+
if (merge.conflict) {
|
|
163
|
+
conflicts.push(upstream.path);
|
|
164
|
+
// Conflict: niet schrijven, oud stempel behouden tot reconciliatie.
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
if (write)
|
|
168
|
+
fsPort.write(upstream.path, merge.contents);
|
|
169
|
+
// Schoon/gemerged: stempel de nieuwe versie en leg de nieuwe basis vast voor volgende upgrades.
|
|
170
|
+
nextFiles[upstream.path] = { templateVersion: toVersion, base: merge.contents };
|
|
171
|
+
}
|
|
172
|
+
const gateOutcome = gate ? gate(files) : undefined;
|
|
173
|
+
const safe = conflicts.length === 0 && (gateOutcome ? gateOutcome.ok : true);
|
|
174
|
+
return {
|
|
175
|
+
fromVersion,
|
|
176
|
+
toVersion,
|
|
177
|
+
files,
|
|
178
|
+
conflicts,
|
|
179
|
+
safe,
|
|
180
|
+
gate: gateOutcome,
|
|
181
|
+
record: { module: record.module, templateVersion: safe ? toVersion : fromVersion, files: nextFiles },
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=three-way-merge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"three-way-merge.js","sourceRoot":"","sources":["../../../scaffolder/core/three-way-merge.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* scaffolder (authentication) — de version-aware materializer van de authentication-capability-module.
|
|
3
|
+
*
|
|
4
|
+
* Composeert het manifest (US-A0801/0802) tot een werkende generate + upgrade-merge, en levert de
|
|
5
|
+
* divergentie-ladder niveau 1–3 (configureren, uitbreiden, materialiseren & mergen). Alle core-functies
|
|
6
|
+
* zijn puur/deterministisch; het wegschrijven en inlezen gaat via een geïnjecteerde fs-port. Geen
|
|
7
|
+
* module-globale mutable state, geen echt filesystem. Dit is een build/dev-tool, geen runtime-mechanisme.
|
|
8
|
+
*/
|
|
9
|
+
export type { FileDescriptor, AuthScaffolderFsPort, MemoryFsPort } from './core/ports.js';
|
|
10
|
+
export { createMemoryFsPort } from './core/ports.js';
|
|
11
|
+
export { materializeAuthModule, stampedVersions } from './core/materialize.js';
|
|
12
|
+
export type { MaterializeOptions, MaterializeResult, MaterializationRecord, MaterializedFile, } from './core/materialize.js';
|
|
13
|
+
export { mergeSurface, upgradeSurface } from './core/three-way-merge.js';
|
|
14
|
+
export type { MergeStatus, MergeInput, MergeResult, MergeMarkerLabels, UpgradeOptions, UpgradeResult, FileUpgradeOutcome, AcceptanceGate, GateOutcome, } from './core/three-way-merge.js';
|
|
15
|
+
export { resolveAuthConfig, filterSurfaceByConfig, authConfigSchema } from './core/config.js';
|
|
16
|
+
export type { EffectiveAuthConfig, ResolvedAuthConfig, AffectedSurface, } from './core/config.js';
|
|
17
|
+
export { defineRegisterFieldExtension, extendRegisterSchema, createPostLoginHookRegistry, defineSlot, createSlotRegistry, AUTH_SLOT_NAMES, } from './core/extend.js';
|
|
18
|
+
export type { RegisterFieldExtension, RegisterFieldExtensionSpec, PostLoginContext, PostLoginHook, PostLoginRunResult, PostLoginHookRegistry, AuthSlotName, SlotDescriptor, SlotRegistry, } from './core/extend.js';
|
|
19
|
+
export { AuthMaterializationConflictError, MissingRequiredPortError, AuthConfigValidationError, } from './core/errors.js';
|
|
20
|
+
export type { AuthConfigViolation } from './core/errors.js';
|
|
21
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../scaffolder/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,YAAY,EAAE,cAAc,EAAE,oBAAoB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAGrD,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC/E,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,uBAAuB,CAAC;AAG/B,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AACzE,YAAY,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,WAAW,GACZ,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC9F,YAAY,EACV,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,4BAA4B,EAC5B,oBAAoB,EACpB,2BAA2B,EAC3B,UAAU,EACV,kBAAkB,EAClB,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,sBAAsB,EACtB,0BAA0B,EAC1B,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,qBAAqB,EACrB,YAAY,EACZ,cAAc,EACd,YAAY,GACb,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,gCAAgC,EAChC,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* scaffolder (authentication) — de version-aware materializer van de authentication-capability-module.
|
|
3
|
+
*
|
|
4
|
+
* Composeert het manifest (US-A0801/0802) tot een werkende generate + upgrade-merge, en levert de
|
|
5
|
+
* divergentie-ladder niveau 1–3 (configureren, uitbreiden, materialiseren & mergen). Alle core-functies
|
|
6
|
+
* zijn puur/deterministisch; het wegschrijven en inlezen gaat via een geïnjecteerde fs-port. Geen
|
|
7
|
+
* module-globale mutable state, geen echt filesystem. Dit is een build/dev-tool, geen runtime-mechanisme.
|
|
8
|
+
*/
|
|
9
|
+
export { createMemoryFsPort } from './core/ports.js';
|
|
10
|
+
// Materialize (US-A0803): surface stampen + all-or-nothing collision-refusal.
|
|
11
|
+
export { materializeAuthModule, stampedVersions } from './core/materialize.js';
|
|
12
|
+
// Three-way-merge / upgrade (US-A0804 / US-A1004).
|
|
13
|
+
export { mergeSurface, upgradeSurface } from './core/three-way-merge.js';
|
|
14
|
+
// Configure (US-A1001): niveau-1-divergentie.
|
|
15
|
+
export { resolveAuthConfig, filterSurfaceByConfig, authConfigSchema } from './core/config.js';
|
|
16
|
+
// Extend (US-A1002): niveau-2-divergentie (additief).
|
|
17
|
+
export { defineRegisterFieldExtension, extendRegisterSchema, createPostLoginHookRegistry, defineSlot, createSlotRegistry, AUTH_SLOT_NAMES, } from './core/extend.js';
|
|
18
|
+
// Fouten.
|
|
19
|
+
export { AuthMaterializationConflictError, MissingRequiredPortError, AuthConfigValidationError, } from './core/errors.js';
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../scaffolder/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,8EAA8E;AAC9E,OAAO,EAAE,qBAAqB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAQ/E,mDAAmD;AACnD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAazE,8CAA8C;AAC9C,OAAO,EAAE,iBAAiB,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAO9F,sDAAsD;AACtD,OAAO,EACL,4BAA4B,EAC5B,oBAAoB,EACpB,2BAA2B,EAC3B,UAAU,EACV,kBAAkB,EAClB,eAAe,GAChB,MAAM,kBAAkB,CAAC;AAa1B,UAAU;AACV,OAAO,EACL,gCAAgC,EAChC,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* AuthField — toegankelijk veld-fragment (surface, design-system-agnostisch). Wrapt de forms-kit
|
|
4
|
+
* `useField(name)` en rendert plain semantische HTML: een `<label>`, een `<input>` en een
|
|
5
|
+
* `aria-live`-foutregio. De accessibiliteits-attributen (`aria-invalid`, `aria-describedby`) komen
|
|
6
|
+
* uit de forms-kit; de foutmeldingen zijn al i18n-resolved door de kit. Vereist een ouder die
|
|
7
|
+
* `useForm(...)` heeft aangeroepen (die provside de form-context). Geen eigen validatie-logica.
|
|
8
|
+
*
|
|
9
|
+
* De host swapt dit desgewenst voor een design-system-veld: de klassen zijn BEM-ish en het label
|
|
10
|
+
* is een named slot, zodat de vorm open blijft.
|
|
11
|
+
*/
|
|
12
|
+
import { useField } from '@seifer-webapp-factory/kits/frontend/forms/vue';
|
|
13
|
+
|
|
14
|
+
const props = withDefaults(
|
|
15
|
+
defineProps<{
|
|
16
|
+
/** Veldnaam (moet als beginwaarde in het ouder-`useForm` bestaan). */
|
|
17
|
+
name: string;
|
|
18
|
+
/** Zichtbaar label (reeds vertaald door de aanroeper). */
|
|
19
|
+
label: string;
|
|
20
|
+
/** HTML input-type. */
|
|
21
|
+
type?: string;
|
|
22
|
+
/** Autocomplete-hint voor wachtwoordmanagers/browsers. */
|
|
23
|
+
autocomplete?: string;
|
|
24
|
+
/** Verplicht-markering (louter presentatie; validatie zit in het schema). */
|
|
25
|
+
required?: boolean;
|
|
26
|
+
}>(),
|
|
27
|
+
{ type: 'text', autocomplete: undefined, required: false },
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const field = useField(props.name);
|
|
31
|
+
const inputId = `auth-field-${props.name}`;
|
|
32
|
+
|
|
33
|
+
// Losse refs teruggeven zodat de template ze auto-unwrapt (geen geneste `.value.value`).
|
|
34
|
+
const { elRef, value, errors, hasError, inputAttrs, errorAttrs, handleBlur } = field;
|
|
35
|
+
</script>
|
|
36
|
+
|
|
37
|
+
<template>
|
|
38
|
+
<div class="auth-field" :class="{ 'auth-field--error': hasError }">
|
|
39
|
+
<label class="auth-field__label" :for="inputId">
|
|
40
|
+
<slot name="label">{{ label }}</slot>
|
|
41
|
+
<span v-if="required" class="auth-field__required" aria-hidden="true">*</span>
|
|
42
|
+
</label>
|
|
43
|
+
|
|
44
|
+
<input
|
|
45
|
+
:id="inputId"
|
|
46
|
+
ref="elRef"
|
|
47
|
+
v-model="value"
|
|
48
|
+
class="auth-field__input"
|
|
49
|
+
:type="type"
|
|
50
|
+
:autocomplete="autocomplete"
|
|
51
|
+
:aria-invalid="inputAttrs['aria-invalid']"
|
|
52
|
+
:aria-describedby="inputAttrs['aria-describedby']"
|
|
53
|
+
@blur="handleBlur"
|
|
54
|
+
/>
|
|
55
|
+
|
|
56
|
+
<ul
|
|
57
|
+
v-if="hasError"
|
|
58
|
+
:id="errorAttrs.id"
|
|
59
|
+
class="auth-field__errors"
|
|
60
|
+
:role="errorAttrs.role"
|
|
61
|
+
:aria-live="errorAttrs['aria-live']"
|
|
62
|
+
>
|
|
63
|
+
<li v-for="(message, index) in errors" :key="index" class="auth-field__error">
|
|
64
|
+
{{ message }}
|
|
65
|
+
</li>
|
|
66
|
+
</ul>
|
|
67
|
+
</div>
|
|
68
|
+
</template>
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"auth.field.email": "Email address",
|
|
3
|
+
"auth.field.password": "Password",
|
|
4
|
+
|
|
5
|
+
"auth.login.title": "Sign in",
|
|
6
|
+
"auth.login.subtitle": "Sign in with your email address and password.",
|
|
7
|
+
"auth.login.submit": "Sign in",
|
|
8
|
+
"auth.login.submitting": "Signing in…",
|
|
9
|
+
"auth.login.success": "You are signed in.",
|
|
10
|
+
"auth.login.forgotLink": "Forgot your password?",
|
|
11
|
+
"auth.login.registerLink": "No account yet? Register",
|
|
12
|
+
|
|
13
|
+
"auth.register.title": "Create account",
|
|
14
|
+
"auth.register.subtitle": "Create an account to get started.",
|
|
15
|
+
"auth.register.submit": "Register",
|
|
16
|
+
"auth.register.submitting": "Registering…",
|
|
17
|
+
"auth.register.success": "Account created. Check your email.",
|
|
18
|
+
"auth.register.passwordHint": "Use at least 8 characters.",
|
|
19
|
+
"auth.register.checkEmailTitle": "Check your email",
|
|
20
|
+
"auth.register.checkEmailBody": "We sent you a verification link. Open it to activate your account.",
|
|
21
|
+
"auth.register.backToLogin": "Back to sign in",
|
|
22
|
+
"auth.register.loginLink": "Already have an account? Sign in",
|
|
23
|
+
|
|
24
|
+
"auth.verify.invalidLinkTitle": "Invalid verification link",
|
|
25
|
+
"auth.verify.invalidLinkBody": "This link is incomplete or invalid. Request a new verification email.",
|
|
26
|
+
"auth.verify.verifying": "Verifying…",
|
|
27
|
+
"auth.verify.successTitle": "Email verified",
|
|
28
|
+
"auth.verify.successBody": "Your email address has been confirmed. You can now sign in.",
|
|
29
|
+
"auth.verify.failedTitle": "Verification failed",
|
|
30
|
+
"auth.verify.failedBody": "We could not verify your email address. The link may have expired.",
|
|
31
|
+
"auth.verify.toLogin": "Go to sign in",
|
|
32
|
+
|
|
33
|
+
"auth.forgot.title": "Forgot password",
|
|
34
|
+
"auth.forgot.subtitle": "Enter your email address and we will send you a reset link.",
|
|
35
|
+
"auth.forgot.submit": "Send reset link",
|
|
36
|
+
"auth.forgot.submitting": "Sending…",
|
|
37
|
+
"auth.forgot.confirmTitle": "Check your email",
|
|
38
|
+
"auth.forgot.confirmBody": "If an account exists for this email address, you will receive an email with instructions to reset your password.",
|
|
39
|
+
"auth.forgot.backToLogin": "Back to sign in",
|
|
40
|
+
|
|
41
|
+
"auth.reset.title": "Set a new password",
|
|
42
|
+
"auth.reset.subtitle": "Choose a new password for your account.",
|
|
43
|
+
"auth.reset.newPassword": "New password",
|
|
44
|
+
"auth.reset.submit": "Save password",
|
|
45
|
+
"auth.reset.submitting": "Saving…",
|
|
46
|
+
"auth.reset.success": "Your password has been reset.",
|
|
47
|
+
"auth.reset.invalidLinkTitle": "Invalid reset link",
|
|
48
|
+
"auth.reset.invalidLinkBody": "This link is incomplete or invalid. Request a new reset link.",
|
|
49
|
+
"auth.reset.requestNew": "Request a new reset link",
|
|
50
|
+
"auth.reset.doneTitle": "Password updated",
|
|
51
|
+
"auth.reset.doneBody": "Your password has been reset. You can now sign in.",
|
|
52
|
+
"auth.reset.toLogin": "Go to sign in",
|
|
53
|
+
|
|
54
|
+
"auth.logout.pending": "Signing out…",
|
|
55
|
+
"auth.logout.doneTitle": "You are signed out",
|
|
56
|
+
"auth.logout.doneBody": "Your session has ended. See you soon!",
|
|
57
|
+
"auth.logout.toLogin": "Sign in again",
|
|
58
|
+
|
|
59
|
+
"auth.error.invalid_credentials": "Email address or password is incorrect.",
|
|
60
|
+
"auth.error.email_taken": "An account with this email address already exists.",
|
|
61
|
+
"auth.error.weak_password": "This password is too weak. Choose a stronger password.",
|
|
62
|
+
"auth.error.token_invalid": "This link is invalid.",
|
|
63
|
+
"auth.error.token_expired": "This link has expired. Request a new one.",
|
|
64
|
+
"auth.error.email_not_verified": "Your email address has not been verified yet. Check your inbox.",
|
|
65
|
+
"auth.error.rate_limited": "Too many attempts. Please try again in a few minutes.",
|
|
66
|
+
"auth.error.csrf_failed": "Your session has expired. Refresh the page and try again.",
|
|
67
|
+
"auth.error.unauthenticated": "You are no longer signed in. Please sign in again.",
|
|
68
|
+
"auth.error.validation_failed": "Please check the details you entered and try again.",
|
|
69
|
+
"auth.error.unknown": "Something went wrong. Please try again later."
|
|
70
|
+
}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"auth.field.email": "E-mailadres",
|
|
3
|
+
"auth.field.password": "Wachtwoord",
|
|
4
|
+
|
|
5
|
+
"auth.login.title": "Inloggen",
|
|
6
|
+
"auth.login.subtitle": "Meld je aan met je e-mailadres en wachtwoord.",
|
|
7
|
+
"auth.login.submit": "Inloggen",
|
|
8
|
+
"auth.login.submitting": "Bezig met inloggen…",
|
|
9
|
+
"auth.login.success": "Je bent ingelogd.",
|
|
10
|
+
"auth.login.forgotLink": "Wachtwoord vergeten?",
|
|
11
|
+
"auth.login.registerLink": "Nog geen account? Registreer je",
|
|
12
|
+
|
|
13
|
+
"auth.register.title": "Account aanmaken",
|
|
14
|
+
"auth.register.subtitle": "Maak een account aan om te beginnen.",
|
|
15
|
+
"auth.register.submit": "Registreren",
|
|
16
|
+
"auth.register.submitting": "Bezig met registreren…",
|
|
17
|
+
"auth.register.success": "Account aangemaakt. Controleer je e-mail.",
|
|
18
|
+
"auth.register.passwordHint": "Gebruik minimaal 8 tekens.",
|
|
19
|
+
"auth.register.checkEmailTitle": "Controleer je e-mail",
|
|
20
|
+
"auth.register.checkEmailBody": "We hebben je een verificatielink gestuurd. Open die om je account te activeren.",
|
|
21
|
+
"auth.register.backToLogin": "Terug naar inloggen",
|
|
22
|
+
"auth.register.loginLink": "Heb je al een account? Log in",
|
|
23
|
+
|
|
24
|
+
"auth.verify.invalidLinkTitle": "Ongeldige verificatielink",
|
|
25
|
+
"auth.verify.invalidLinkBody": "Deze link is onvolledig of ongeldig. Vraag een nieuwe verificatiemail aan.",
|
|
26
|
+
"auth.verify.verifying": "Bezig met verifiëren…",
|
|
27
|
+
"auth.verify.successTitle": "E-mail geverifieerd",
|
|
28
|
+
"auth.verify.successBody": "Je e-mailadres is bevestigd. Je kunt nu inloggen.",
|
|
29
|
+
"auth.verify.failedTitle": "Verificatie mislukt",
|
|
30
|
+
"auth.verify.failedBody": "We konden je e-mailadres niet verifiëren. De link is mogelijk verlopen.",
|
|
31
|
+
"auth.verify.toLogin": "Naar inloggen",
|
|
32
|
+
|
|
33
|
+
"auth.forgot.title": "Wachtwoord vergeten",
|
|
34
|
+
"auth.forgot.subtitle": "Vul je e-mailadres in; we sturen je een herstellink.",
|
|
35
|
+
"auth.forgot.submit": "Stuur herstellink",
|
|
36
|
+
"auth.forgot.submitting": "Bezig met versturen…",
|
|
37
|
+
"auth.forgot.confirmTitle": "Controleer je e-mail",
|
|
38
|
+
"auth.forgot.confirmBody": "Als er een account bij dit e-mailadres hoort, ontvang je een e-mail met instructies om je wachtwoord te herstellen.",
|
|
39
|
+
"auth.forgot.backToLogin": "Terug naar inloggen",
|
|
40
|
+
|
|
41
|
+
"auth.reset.title": "Nieuw wachtwoord instellen",
|
|
42
|
+
"auth.reset.subtitle": "Kies een nieuw wachtwoord voor je account.",
|
|
43
|
+
"auth.reset.newPassword": "Nieuw wachtwoord",
|
|
44
|
+
"auth.reset.submit": "Wachtwoord opslaan",
|
|
45
|
+
"auth.reset.submitting": "Bezig met opslaan…",
|
|
46
|
+
"auth.reset.success": "Je wachtwoord is opnieuw ingesteld.",
|
|
47
|
+
"auth.reset.invalidLinkTitle": "Ongeldige herstellink",
|
|
48
|
+
"auth.reset.invalidLinkBody": "Deze link is onvolledig of ongeldig. Vraag een nieuwe herstellink aan.",
|
|
49
|
+
"auth.reset.requestNew": "Nieuwe herstellink aanvragen",
|
|
50
|
+
"auth.reset.doneTitle": "Wachtwoord bijgewerkt",
|
|
51
|
+
"auth.reset.doneBody": "Je wachtwoord is opnieuw ingesteld. Je kunt nu inloggen.",
|
|
52
|
+
"auth.reset.toLogin": "Naar inloggen",
|
|
53
|
+
|
|
54
|
+
"auth.logout.pending": "Bezig met uitloggen…",
|
|
55
|
+
"auth.logout.doneTitle": "Je bent uitgelogd",
|
|
56
|
+
"auth.logout.doneBody": "Je sessie is beëindigd. Tot ziens!",
|
|
57
|
+
"auth.logout.toLogin": "Opnieuw inloggen",
|
|
58
|
+
|
|
59
|
+
"auth.error.invalid_credentials": "E-mailadres of wachtwoord is onjuist.",
|
|
60
|
+
"auth.error.email_taken": "Er bestaat al een account met dit e-mailadres.",
|
|
61
|
+
"auth.error.weak_password": "Dit wachtwoord is te zwak. Kies een sterker wachtwoord.",
|
|
62
|
+
"auth.error.token_invalid": "Deze link is ongeldig.",
|
|
63
|
+
"auth.error.token_expired": "Deze link is verlopen. Vraag een nieuwe aan.",
|
|
64
|
+
"auth.error.email_not_verified": "Je e-mailadres is nog niet geverifieerd. Controleer je inbox.",
|
|
65
|
+
"auth.error.rate_limited": "Te veel pogingen. Probeer het over enkele minuten opnieuw.",
|
|
66
|
+
"auth.error.csrf_failed": "Je sessie is verlopen. Vernieuw de pagina en probeer het opnieuw.",
|
|
67
|
+
"auth.error.unauthenticated": "Je bent niet (meer) ingelogd. Log opnieuw in.",
|
|
68
|
+
"auth.error.validation_failed": "Controleer de ingevulde gegevens en probeer het opnieuw.",
|
|
69
|
+
"auth.error.unknown": "Er ging iets mis. Probeer het later opnieuw."
|
|
70
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-A0305 — Route-middleware `auth` (surface, gematerialiseerd, Nuxt). Beschermt auth-required
|
|
3
|
+
* routes door de pinned `authRequiredGuard` te composeren: anonieme bezoekers worden naar `/login`
|
|
4
|
+
* geredirect met de oorspronkelijke route als `redirect`-terugkeer-parameter. De sessie-status komt
|
|
5
|
+
* uit de door de plugin geprovide accessor (`$authIsAuthenticated`) — geen module-globale state.
|
|
6
|
+
*
|
|
7
|
+
* Gebruik in een pagina: `definePageMeta({ middleware: 'auth' })`.
|
|
8
|
+
*/
|
|
9
|
+
import { authRequiredGuard } from '../../src/index.js';
|
|
10
|
+
|
|
11
|
+
// Nuxt auto-imports (host-context).
|
|
12
|
+
declare const defineNuxtRouteMiddleware: (
|
|
13
|
+
fn: (to: { path: string; fullPath: string }) => unknown,
|
|
14
|
+
) => unknown;
|
|
15
|
+
declare const useNuxtApp: () => { $authIsAuthenticated?: () => boolean };
|
|
16
|
+
declare const navigateTo: (to: { path: string; query?: Record<string, string> }) => unknown;
|
|
17
|
+
|
|
18
|
+
export default defineNuxtRouteMiddleware((to) => {
|
|
19
|
+
const isAuthenticated = useNuxtApp().$authIsAuthenticated ?? (() => false);
|
|
20
|
+
const guard = authRequiredGuard({ isAuthenticated, loginPath: '/login' });
|
|
21
|
+
const decision = guard({ path: to.path, fullPath: to.fullPath });
|
|
22
|
+
if (decision !== true) {
|
|
23
|
+
return navigateTo(decision);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* US-A0305 — Route-middleware `guest` (surface, gematerialiseerd, Nuxt). Weert reeds-ingelogde
|
|
3
|
+
* bezoekers van guest-only routes (bv. `/login`, `/register`) door de pinned `guestOnlyGuard` te
|
|
4
|
+
* composeren: een geauthenticeerde sessie wordt naar de home (`/`) geredirect. De sessie-status komt
|
|
5
|
+
* uit de door de plugin geprovide accessor (`$authIsAuthenticated`) — geen module-globale state.
|
|
6
|
+
*
|
|
7
|
+
* Gebruik in een pagina: `definePageMeta({ middleware: 'guest' })`.
|
|
8
|
+
*/
|
|
9
|
+
import { guestOnlyGuard } from '../../src/index.js';
|
|
10
|
+
|
|
11
|
+
// Nuxt auto-imports (host-context).
|
|
12
|
+
declare const defineNuxtRouteMiddleware: (
|
|
13
|
+
fn: (to: { path: string; fullPath: string }) => unknown,
|
|
14
|
+
) => unknown;
|
|
15
|
+
declare const useNuxtApp: () => { $authIsAuthenticated?: () => boolean };
|
|
16
|
+
declare const navigateTo: (to: { path: string; query?: Record<string, string> }) => unknown;
|
|
17
|
+
|
|
18
|
+
export default defineNuxtRouteMiddleware((to) => {
|
|
19
|
+
const isAuthenticated = useNuxtApp().$authIsAuthenticated ?? (() => false);
|
|
20
|
+
const guard = guestOnlyGuard({ isAuthenticated, homePath: '/' });
|
|
21
|
+
const decision = guard({ path: to.path, fullPath: to.fullPath });
|
|
22
|
+
if (decision !== true) {
|
|
23
|
+
return navigateTo(decision);
|
|
24
|
+
}
|
|
25
|
+
});
|