@ofidj/generator-fidj 3.19.0 → 3.21.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.0",
19
- "@ofidj/node": "^3.19.0"
18
+ "@ofidj/entry": "^3.21.0",
19
+ "@ofidj/node": "^3.21.0"
20
20
  },
21
21
  "devDependencies": {
22
22
  "@types/node": "^22.0.0",
@@ -1,4 +1,4 @@
1
- import {signInErrorMessage, formatDate, agreementRequired, agreementFromRefusal, verificationPending, pollVerification, rememberSignIn, forgetSignIn, signInHint, type SigninShape} from "@ofidj/entry";
1
+ import {signInErrorMessage, formatDate, agreementRequired, agreementFromRefusal, agreementAddress, type ServiceAgreement, verificationPending, pollVerification, rememberSignIn, forgetSignIn, signInHint, type SigninShape} from "@ofidj/entry";
2
2
  import {agreementScreen, bindAgreementScreen, bindPasswordReveal, acceptedAgreement, verificationWait, providerEntry, showEmailEntry, showVersionBadge, escape, masthead, highlightCells, badgeStrip, credentialFields, accountForm, passkeySupported, passkeyAssertion, walletDoor, memberCard, bindMemberHistory, 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";
@@ -41,7 +41,7 @@ let signInEmail = "";
41
41
  let signInPassword = "";
42
42
  // The agreement this app is owed, once the API has said so, and the address a
43
43
  // just-created account is waiting on. Only one of them is ever set.
44
- let pendingAgreement: {version: string; text: string} | null = null;
44
+ let pendingAgreement: ServiceAgreement | null = null;
45
45
  let awaitingVerification = "";
46
46
  let verificationResent = false;
47
47
  let verificationNotice = "";
@@ -704,7 +704,7 @@ function render() {
704
704
  // form's place rather than sitting under it: the credentials were accepted,
705
705
  // and what is left is a decision about this app.
706
706
  if (pendingAgreement && element("signin")) {
707
- element("signin")!.innerHTML = agreementScreen(config.title, pendingAgreement, `${config.apiEndpoint}/apps/${encodeURIComponent(config.appId)}/agreements/${encodeURIComponent(pendingAgreement.version || "")}`);
707
+ element("signin")!.innerHTML = agreementScreen(config.title, pendingAgreement, agreementAddress(config.apiEndpoint, config.appId, pendingAgreement));
708
708
  bindAgreementScreen(element<HTMLFormElement>("signin"));
709
709
  }
710
710
  // The app's own form, for whoever came to type a password. Folded away rather
@@ -897,7 +897,12 @@ async function readAgreement() {
897
897
  agreement.version &&
898
898
  typeof agreement?.text === "string" &&
899
899
  agreement.text
900
- ? {version: agreement.version, text: agreement.text}
900
+ ? {
901
+ version: agreement.version,
902
+ text: agreement.text,
903
+ ...(typeof agreement.language === "string" ? {language: agreement.language} : {}),
904
+ ...(typeof agreement.href === "string" ? {href: agreement.href} : {}),
905
+ }
901
906
  : null;
902
907
  } catch {
903
908
  return null;
@@ -1041,10 +1046,11 @@ function accountRows() {
1041
1046
 
1042
1047
  function privacyBlock() {
1043
1048
  const version = String((consent as Record<string, unknown>).termsVersion || "");
1049
+ const href = (consent as Record<string, unknown>).termsHref;
1044
1050
  return memberCard({
1045
1051
  consent,
1046
1052
  history,
1047
- agreementHref: `${config.apiEndpoint}/apps/${encodeURIComponent(config.appId)}/agreements/${encodeURIComponent(version)}`,
1053
+ agreementHref: agreementAddress(config.apiEndpoint, config.appId, {version, href: typeof href === "string" ? href : undefined}),
1048
1054
  owner: roles.includes("Owner"),
1049
1055
  leaving,
1050
1056
  manageHref: `${config.dashboardUrl}/#/my/gdpr`,
@@ -1,4 +1,4 @@
1
- import {agreementRequired, agreementFromRefusal, signInErrorMessage, rememberSignIn, forgetSignIn, formatDate, type SigninShape} from "@ofidj/entry";
1
+ import {agreementRequired, agreementFromRefusal, agreementAddress, type ServiceAgreement, signInErrorMessage, rememberSignIn, forgetSignIn, formatDate, type SigninShape} from "@ofidj/entry";
2
2
  import {acceptedAgreement, agreementScreen, memberCard, bindMemberHistory, 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";
@@ -30,7 +30,7 @@ let settings: Settings;
30
30
  let session: Session | null = null;
31
31
  let notes: Note[] = [];
32
32
  let privacy: {
33
- consent: Record<string, boolean>;
33
+ consent: Record<string, boolean> & {termsVersion?: string; termsHref?: string};
34
34
  history: Array<{ type: string; granted: boolean; changedAt: string }>;
35
35
  } | null = null;
36
36
  let view = "workspace";
@@ -42,7 +42,7 @@ let signInEmail = "";
42
42
  let signInPassword = "";
43
43
  // The agreement this app is owed, once the API has said so. There is no
44
44
  // account creation here, so there is no verification wait to hold either.
45
- let pendingAgreement: {version: string; text: string} | null = null;
45
+ let pendingAgreement: ServiceAgreement | null = null;
46
46
  // Whether the person asked for the app's own form: the entry is rebuilt on every
47
47
  // render, and a refused sign-in is a render, so it has to be remembered or the
48
48
  // form folds away under the complaint about it.
@@ -219,7 +219,10 @@ function render() {
219
219
  consent: privacy?.consent || {},
220
220
  history: privacy?.history || [],
221
221
  agreementHref: privacy?.consent.termsVersion
222
- ? `${settings.apiEndpoint}/apps/${encodeURIComponent(settings.appId)}/agreements/${encodeURIComponent(String(privacy.consent.termsVersion))}`
222
+ ? agreementAddress(settings.apiEndpoint, settings.appId, {
223
+ version: String(privacy.consent.termsVersion),
224
+ href: privacy.consent.termsHref,
225
+ })
223
226
  : undefined,
224
227
  owner: session.roles.includes("Owner"),
225
228
  leaving,
@@ -232,7 +235,7 @@ function render() {
232
235
  <footer>Built with Fidj · One identity. Separate choices for every app.</footer></main>`;
233
236
  // The agreement takes the form's place once the API says this app is owed one.
234
237
  if (pendingAgreement && el("signin")) {
235
- el("signin")!.innerHTML = agreementScreen(settings.title, pendingAgreement, `${settings.apiEndpoint}/apps/${encodeURIComponent(settings.appId)}/agreements/${encodeURIComponent(pendingAgreement.version || "")}`);
238
+ el("signin")!.innerHTML = agreementScreen(settings.title, pendingAgreement, agreementAddress(settings.apiEndpoint, settings.appId, pendingAgreement));
236
239
  bindAgreementScreen(el<HTMLFormElement>("signin"));
237
240
  }
238
241
  // The app's own form, folded away under the Fidj door rather than beside it.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ofidj/generator-fidj",
3
- "version": "3.19.0",
3
+ "version": "3.21.0",
4
4
  "description": "Generate a TypeScript app with Fidj sign-in, live server-side roles and per-app privacy.",
5
5
  "homepage": "https://fidj.ovh",
6
6
  "bugs": {