@ofidj/generator-fidj 3.17.0 → 3.18.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.
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"privacy:rehearse": "npm run build && node --test test/server.test.mjs"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@ofidj/entry": "^3.
|
|
19
|
-
"@ofidj/node": "^3.
|
|
18
|
+
"@ofidj/entry": "^3.18.0",
|
|
19
|
+
"@ofidj/node": "^3.18.0"
|
|
20
20
|
},
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@types/node": "^22.0.0",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {signInErrorMessage, formatDate,
|
|
2
|
-
import {agreementScreen, bindAgreementScreen, bindPasswordReveal, acceptedAgreement, verificationWait, providerEntry, showEmailEntry, showVersionBadge, escape, masthead, highlightCells, badgeStrip, credentialFields, accountForm, passkeySupported, passkeyAssertion, walletDoor, oidcInteractionMarkup, oidcInteractionStyles, bindOidcInteraction} from "@ofidj/entry/dom";
|
|
1
|
+
import {signInErrorMessage, formatDate, agreementRequired, agreementFromRefusal, verificationPending, pollVerification, rememberSignIn, forgetSignIn, signInHint, type SigninShape} from "@ofidj/entry";
|
|
2
|
+
import {agreementScreen, bindAgreementScreen, bindPasswordReveal, acceptedAgreement, verificationWait, providerEntry, showEmailEntry, showVersionBadge, escape, masthead, highlightCells, badgeStrip, credentialFields, accountForm, passkeySupported, passkeyAssertion, walletDoor, memberCard, oidcInteractionMarkup, oidcInteractionStyles, bindOidcInteraction} from "@ofidj/entry/dom";
|
|
3
3
|
import {openProviderWindow, relayProviderAnswer, type ProviderWindow} from "@ofidj/entry/window";
|
|
4
4
|
import { FidjNodeService, FidjOidcClient } from "@ofidj/node";
|
|
5
5
|
import config from "../app.config.json";
|
|
@@ -412,16 +412,16 @@ function signInThroughProvider(
|
|
|
412
412
|
void action(async () => {
|
|
413
413
|
let url: string;
|
|
414
414
|
try {
|
|
415
|
-
//
|
|
416
|
-
//
|
|
417
|
-
//
|
|
418
|
-
//
|
|
419
|
-
//
|
|
420
|
-
//
|
|
415
|
+
// Somebody who has just signed out of this app did not ask to be walked
|
|
416
|
+
// straight back in: the provider still knows the browser and would answer
|
|
417
|
+
// with a code and no screen. So the door asks which account — the consent
|
|
418
|
+
// screen names the one Fidj recognises and offers another. It does not ask
|
|
419
|
+
// for a password: prompt=login told Fidj "this is not me" and ended the
|
|
420
|
+
// Fidj session along with the app's.
|
|
421
421
|
url = await oidc.beginLogin(
|
|
422
422
|
options.prompt || options.silent || !oidc.signedOutHere()
|
|
423
423
|
? options
|
|
424
|
-
: {...options, prompt: "
|
|
424
|
+
: {...options, prompt: "consent"},
|
|
425
425
|
);
|
|
426
426
|
} catch (error) {
|
|
427
427
|
providerWindow?.giveUp();
|
|
@@ -917,7 +917,7 @@ function wirePrivacy() {
|
|
|
917
917
|
navigate("signin");
|
|
918
918
|
}),
|
|
919
919
|
);
|
|
920
|
-
element("terms")?.addEventListener(
|
|
920
|
+
element("accept-terms")?.addEventListener(
|
|
921
921
|
"click",
|
|
922
922
|
() =>
|
|
923
923
|
void action(async () => {
|
|
@@ -1001,36 +1001,15 @@ function accountRows() {
|
|
|
1001
1001
|
}
|
|
1002
1002
|
|
|
1003
1003
|
function privacyBlock() {
|
|
1004
|
-
const
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
:
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
)
|
|
1014
|
-
.join("");
|
|
1015
|
-
const entries = history.length
|
|
1016
|
-
? history
|
|
1017
|
-
.slice()
|
|
1018
|
-
.reverse()
|
|
1019
|
-
.map(
|
|
1020
|
-
(entry) =>
|
|
1021
|
-
`<p>${escape(formatDate(entry.changedAt, "datetime"))} · ${escape(entry.type)} ${entry.granted ? "given" : "withdrawn"}</p>`,
|
|
1022
|
-
)
|
|
1023
|
-
.join("")
|
|
1024
|
-
: "<p>No changes yet.</p>";
|
|
1025
|
-
const leave = roles.includes("Owner")
|
|
1026
|
-
? "<small>You own this app: hand it over or delete it on Fidj before leaving.</small>"
|
|
1027
|
-
: leaving
|
|
1028
|
-
? '<p>Your membership and what this app holds for you will be erased. Your other apps remain available.</p><button id="confirm-leave" class="danger">Leave & erase</button><button id="cancel-leave">Keep my membership</button>'
|
|
1029
|
-
: '<button id="leave" class="danger">Leave & erase</button>';
|
|
1030
|
-
return `<h2>Your membership</h2><div class="member-rows">${agreementRow}${choices}</div>
|
|
1031
|
-
<details class="member-history"><summary>History</summary>${entries}</details>
|
|
1032
|
-
<div class="member-actions"><button id="export">Export</button>${leave}</div>
|
|
1033
|
-
<p class="leaving"><a href="${escape(config.dashboardUrl)}/#/my/gdpr" target="_blank" rel="noopener noreferrer">Open Fidj to manage every app you use ↗</a></p>`;
|
|
1004
|
+
const version = String((consent as Record<string, unknown>).termsVersion || "");
|
|
1005
|
+
return memberCard({
|
|
1006
|
+
consent,
|
|
1007
|
+
history,
|
|
1008
|
+
agreementHref: `${config.apiEndpoint}/apps/${encodeURIComponent(config.appId)}/agreements/${encodeURIComponent(version)}`,
|
|
1009
|
+
owner: roles.includes("Owner"),
|
|
1010
|
+
leaving,
|
|
1011
|
+
manageHref: `${config.dashboardUrl}/#/my/gdpr`,
|
|
1012
|
+
});
|
|
1034
1013
|
}
|
|
1035
1014
|
|
|
1036
1015
|
// ------------------------------------------------ signing in, for the provider
|
|
@@ -1059,6 +1038,8 @@ type Interaction = {
|
|
|
1059
1038
|
recognisedEmail?: string;
|
|
1060
1039
|
// The passkey door's challenge, on the login step.
|
|
1061
1040
|
passkey?: {ticket: string; options: unknown};
|
|
1041
|
+
// The recognised person's agreement is on file at the version in force.
|
|
1042
|
+
agreementAccepted?: boolean;
|
|
1062
1043
|
action: string;
|
|
1063
1044
|
};
|
|
1064
1045
|
let interactionId = "";
|
|
@@ -1184,6 +1165,7 @@ function interactionScreen() {
|
|
|
1184
1165
|
agreementHref: details.termsUri || undefined,
|
|
1185
1166
|
recognisedEmail: details.recognisedEmail || undefined,
|
|
1186
1167
|
passkey: details.passkey,
|
|
1168
|
+
agreementAccepted: details.agreementAccepted,
|
|
1187
1169
|
logoSrc: "./fidj-logo.png",
|
|
1188
1170
|
})}`;
|
|
1189
1171
|
bindOidcInteraction(root);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import {agreementRequired, agreementFromRefusal, signInErrorMessage, rememberSignIn, forgetSignIn, formatDate, type SigninShape} from "@ofidj/entry";
|
|
2
|
-
import {acceptedAgreement, agreementScreen, bindAgreementScreen, bindPasswordReveal, providerEntry, showEmailEntry, showVersionBadge} from "@ofidj/entry/dom";
|
|
2
|
+
import {acceptedAgreement, agreementScreen, memberCard, bindAgreementScreen, bindPasswordReveal, providerEntry, showEmailEntry, showVersionBadge} from "@ofidj/entry/dom";
|
|
3
3
|
import {openProviderWindow, relayProviderAnswer, type ProviderWindow} from "@ofidj/entry/window";
|
|
4
4
|
import { FidjNodeService, FidjOidcClient } from "@ofidj/node";
|
|
5
5
|
import "@ofidj/entry/style.css";
|
|
@@ -224,18 +224,18 @@ function render() {
|
|
|
224
224
|
${
|
|
225
225
|
view === "workspace"
|
|
226
226
|
? `<section class="workspace"><div><div class="section-heading"><h2>Your notes</h2><span>${notes.length} saved</span></div>${notes.length ? notes.map((note) => `<article class="card note"><small>${escape(formatDate(note.createdAt, "datetime"))}</small><h3>${escape(note.title)}</h3><p>${escape(note.body)}</p></article>`).join("") : `<article class="card empty"><span>✳</span><h3>Room for your next idea.</h3><p>Your saved notes will appear here. Only you can read your notes.</p></article>`}</div><form id="note" class="card"><p class="eyebrow">CAPTURE SOMETHING</p><h2>A fresh note</h2><p>${canWrite ? "You have permission to save notes." : "Ask your app owner for Editor access to save notes."}</p><label for="note-title">Title</label><input id="note-title" maxlength="120" required ${!canWrite ? "disabled" : ""}><label for="note-body">Your note</label><textarea id="note-body" rows="6" maxlength="5000" ${!canWrite ? "disabled" : ""}></textarea><button class="primary" type="submit" ${!canWrite ? "disabled" : ""}>Save note</button><small>Your notes are saved by this app and survive a server restart.</small></form></section>`
|
|
227
|
-
: `<section class="
|
|
228
|
-
privacy?.
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
}
|
|
227
|
+
: `<section class="card privacy-card">${memberCard({
|
|
228
|
+
consent: privacy?.consent || {},
|
|
229
|
+
history: privacy?.history || [],
|
|
230
|
+
agreementHref: privacy?.consent.termsVersion
|
|
231
|
+
? `${settings.apiEndpoint}/apps/${encodeURIComponent(settings.appId)}/agreements/${encodeURIComponent(String(privacy.consent.termsVersion))}`
|
|
232
|
+
: undefined,
|
|
233
|
+
owner: session.roles.includes("Owner"),
|
|
234
|
+
leaving,
|
|
235
|
+
leaveScope:
|
|
236
|
+
"Your membership, your choices and your notes in this app will be erased. Your Fidj account and other apps remain available.",
|
|
237
|
+
manageHref: `${settings.dashboardUrl}/#/my/gdpr`,
|
|
238
|
+
})}</section>`
|
|
239
239
|
}`
|
|
240
240
|
}
|
|
241
241
|
<footer>Built with Fidj · One identity. Separate choices for every app.</footer></main>`;
|
|
@@ -348,7 +348,7 @@ function render() {
|
|
|
348
348
|
void action(async () => {
|
|
349
349
|
await api("privacy", "PUT", { terms: true });
|
|
350
350
|
await load();
|
|
351
|
-
notice = "
|
|
351
|
+
notice = "Service agreement accepted.";
|
|
352
352
|
}),
|
|
353
353
|
);
|
|
354
354
|
el("export")?.addEventListener(
|