@ofidj/entry 3.10.0 → 3.10.1
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/index.d.ts +1 -0
- package/index.js +2 -1
- package/package.json +1 -1
- package/screens.d.ts +19 -0
- package/screens.js +52 -0
package/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export { agreementMarkup, acceptedAgreement, signInErrorMessage, bindAgreement, providerEntry, signInHint, rememberSignIn, forgetSignIn, showEmailEntry, type SigninShape, } from "./service-agreement.js";
|
|
2
2
|
export { openProviderWindow, relayProviderAnswer, type ProviderWindow, } from "./provider-window.js";
|
|
3
3
|
export { showVersionBadge } from "./version.js";
|
|
4
|
+
export { escape, masthead, highlightCells, badgeStrip, credentialFields, accountForm, returnNotice, type AccountState, } from "./screens.js";
|
package/index.js
CHANGED
|
@@ -8,4 +8,5 @@
|
|
|
8
8
|
export { agreementMarkup, acceptedAgreement, signInErrorMessage, bindAgreement, providerEntry, signInHint, rememberSignIn, forgetSignIn, showEmailEntry, } from "./service-agreement.js";
|
|
9
9
|
export { openProviderWindow, relayProviderAnswer, } from "./provider-window.js";
|
|
10
10
|
export { showVersionBadge } from "./version.js";
|
|
11
|
-
|
|
11
|
+
export { escape, masthead, highlightCells, badgeStrip, credentialFields, accountForm, returnNotice, } from "./screens.js";
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsZ0NBQWdDO0FBQ2hDLEVBQUU7QUFDRiw4RUFBOEU7QUFDOUUseUVBQXlFO0FBQ3pFLDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsbURBQW1EO0FBQ25ELE9BQU8sRUFDTCxlQUFlLEVBQ2YsaUJBQWlCLEVBQ2pCLGtCQUFrQixFQUNsQixhQUFhLEVBQ2IsYUFBYSxFQUNiLFVBQVUsRUFDVixjQUFjLEVBQ2QsWUFBWSxFQUNaLGNBQWMsR0FFZixNQUFNLHdCQUF3QixDQUFDO0FBQ2hDLE9BQU8sRUFDTCxrQkFBa0IsRUFDbEIsbUJBQW1CLEdBRXBCLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ2hELE9BQU8sRUFDTCxNQUFNLEVBQ04sUUFBUSxFQUNSLGNBQWMsRUFDZCxVQUFVLEVBQ1YsZ0JBQWdCLEVBQ2hCLFdBQVcsRUFDWCxZQUFZLEdBRWIsTUFBTSxjQUFjLENBQUMifQ==
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ofidj/entry",
|
|
3
|
-
"version": "3.10.
|
|
3
|
+
"version": "3.10.1",
|
|
4
4
|
"description": "The Fidj entry: sign-in, account recovery, the service agreement and the design system, shared verbatim by Fidj, the generated apps and the console.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
package/screens.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export declare const escape: (value: unknown) => string;
|
|
2
|
+
export declare function masthead(logo: string, title: string): string;
|
|
3
|
+
export declare function highlightCells(entries?: Array<{
|
|
4
|
+
heading: string;
|
|
5
|
+
body: string;
|
|
6
|
+
}>): string;
|
|
7
|
+
export declare function badgeStrip(entries?: string[]): string;
|
|
8
|
+
export declare function credentialFields(state: {
|
|
9
|
+
email: string;
|
|
10
|
+
password: string;
|
|
11
|
+
}): string;
|
|
12
|
+
export type AccountState = {
|
|
13
|
+
linkToken?: string;
|
|
14
|
+
verificationConfirmed?: boolean;
|
|
15
|
+
emailVerified?: boolean;
|
|
16
|
+
accountEmail?: string;
|
|
17
|
+
};
|
|
18
|
+
export declare function accountForm(route: string, state: AccountState): string;
|
|
19
|
+
export declare function returnNotice(asking: string): string;
|
package/screens.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// The screens the entry draws, as markup.
|
|
2
|
+
//
|
|
3
|
+
// Lifted out of generator-fidj's content.ts, where the only way to ship them
|
|
4
|
+
// was to generate an app. What stayed behind is the shell that holds them:
|
|
5
|
+
// the sign-in screen nests signin-trust inside its inner div and the
|
|
6
|
+
// interaction screen makes it a sibling, so a single shell builder would have
|
|
7
|
+
// had to change one of them. That is a decision, not a move.
|
|
8
|
+
export const escape = (value) => String(value ?? "").replace(/[&<>"']/g, (char) => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[char]);
|
|
9
|
+
// The app's own mark beside its own name, decorative because the name is right
|
|
10
|
+
// there: every shell opens with this.
|
|
11
|
+
export function masthead(logo, title) {
|
|
12
|
+
return `<header class="signin-masthead"><img class="app-mark" src="${escape(logo)}" alt=""><strong>${escape(title)}</strong></header>`;
|
|
13
|
+
}
|
|
14
|
+
export function highlightCells(entries) {
|
|
15
|
+
if (!entries?.length)
|
|
16
|
+
return "";
|
|
17
|
+
return `<div class="signin-highlights">${entries
|
|
18
|
+
.map((entry, index) => `<article><p class="eyebrow">${String(index + 1).padStart(2, "0")}</p><h2>${escape(entry.heading)}</h2><p>${escape(entry.body)}</p></article>`)
|
|
19
|
+
.join("")}</div>`;
|
|
20
|
+
}
|
|
21
|
+
export function badgeStrip(entries) {
|
|
22
|
+
if (!entries?.length)
|
|
23
|
+
return "";
|
|
24
|
+
return `<footer class="signin-badges">${entries
|
|
25
|
+
.map((entry) => `<span>${escape(entry)}</span>`)
|
|
26
|
+
.join("")}</footer>`;
|
|
27
|
+
}
|
|
28
|
+
// Both doors, and what was already typed. The entry is rebuilt on every render
|
|
29
|
+
// and a refused sign-in is a render, so the values come back in rather than
|
|
30
|
+
// being lost with the markup that held them.
|
|
31
|
+
export function credentialFields(state) {
|
|
32
|
+
return `<label for="email">Email</label><input id="email" type="email" value="${escape(state.email)}" placeholder="you@company.com" autocomplete="username"><div class="field-head"><label for="password">Password</label><a href="#/forgot">Forgot?</a></div><div class="password-field"><input id="password" type="password" value="${escape(state.password)}" placeholder="••••••••••" autocomplete="current-password"><button type="button" id="reveal" aria-controls="password">Show</button></div><button class="primary" type="submit" name="entry" value="credentials">Continue</button><button class="secondary" type="submit" name="signup" value="true">Create an account</button>`;
|
|
33
|
+
}
|
|
34
|
+
// The four account screens. My account is shown inside the app; the recovery
|
|
35
|
+
// and verification ones are reached without a session and stand alone.
|
|
36
|
+
export function accountForm(route, state) {
|
|
37
|
+
return route === "forgot"
|
|
38
|
+
? `<h2>Reset your password</h2><p>We’ll email you a link to choose a new password for your shared Fidj account.</p><form id="recovery"><label for="recovery-email">Email address</label><input id="recovery-email" type="email" autocomplete="email" required><button class="primary">Send reset link</button></form>`
|
|
39
|
+
: route === "reset"
|
|
40
|
+
? `<h2>Choose a new password</h2><p>This changes your Fidj password across all your apps and signs out existing sessions.</p>${state.linkToken ? '<form id="recovery"><label for="new-password">New password</label><input id="new-password" type="password" autocomplete="new-password" minlength="12" required><label for="confirm-password">Confirm password</label><input id="confirm-password" type="password" autocomplete="new-password" minlength="12" required><p>Use at least 12 characters (up to 72 UTF-8 bytes).</p><button class="primary">Save new password</button></form>' : '<p>Request a new link if you no longer have an active reset link.</p><a href="#/forgot">Request a reset link</a>'}`
|
|
41
|
+
: route === "verify"
|
|
42
|
+
? `<h2>${state.verificationConfirmed ? "Email verified" : "Verify your email"}</h2>${state.verificationConfirmed ? "<p>Your account is ready. Return to your app to continue.</p>" : "<p>Confirm that this email address belongs to you.</p>"}${state.verificationConfirmed ? "" : state.linkToken ? '<form id="recovery"><button class="primary">Confirm email address</button></form>' : "<p>Sign in to your account to request a new verification email.</p>"}`
|
|
43
|
+
: `<h2>My Fidj account</h2><p class="account-identity">Signed in as <strong>${escape(state.accountEmail)}</strong></p><p>Your identity is shared across your apps. Privacy choices remain separate for each app.</p><p id="verification-status">${state.emailVerified ? "Your email address is verified." : "Your email is not verified yet."}</p><button id="check-verification">Refresh verification status</button>${state.emailVerified ? "" : '<button id="resend-verification">Send verification email</button>'}<p><a href="#/forgot">Reset my password</a></p>`;
|
|
44
|
+
}
|
|
45
|
+
// A window that opened on its own, over the page somebody was on, owes them the
|
|
46
|
+
// way out before it asks for anything. Naming the app they came from is also the
|
|
47
|
+
// only thing on this screen that they can check against what they were doing a
|
|
48
|
+
// second ago — which is exactly what a page asking for a password should offer.
|
|
49
|
+
export function returnNotice(asking) {
|
|
50
|
+
return `<p class="signin-return" role="note">When you are done, this window closes and takes you back to ${escape(asking)}.</p>`;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2NyZWVucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9zY3JlZW5zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLDBDQUEwQztBQUMxQyxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLDJFQUEyRTtBQUMzRSxxRUFBcUU7QUFDckUsOEVBQThFO0FBQzlFLDZEQUE2RDtBQUU3RCxNQUFNLENBQUMsTUFBTSxNQUFNLEdBQUcsQ0FBQyxLQUFjLEVBQUUsRUFBRSxDQUN2QyxNQUFNLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FDekIsVUFBVSxFQUNWLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FDUCxDQUFDLEVBQUUsR0FBRyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FDdkUsSUFBSSxDQUNKLENBQ0wsQ0FBQztBQUVKLCtFQUErRTtBQUMvRSxzQ0FBc0M7QUFDdEMsTUFBTSxVQUFVLFFBQVEsQ0FBQyxJQUFZLEVBQUUsS0FBYTtJQUNsRCxPQUFPLDhEQUE4RCxNQUFNLENBQUMsSUFBSSxDQUFDLG9CQUFvQixNQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDO0FBQ3pJLENBQUM7QUFFRCxNQUFNLFVBQVUsY0FBYyxDQUM1QixPQUFrRDtJQUVsRCxJQUFJLENBQUMsT0FBTyxFQUFFLE1BQU07UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUNoQyxPQUFPLGtDQUFrQyxPQUFPO1NBQzdDLEdBQUcsQ0FDRixDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUNmLCtCQUErQixNQUFNLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLFdBQVcsTUFBTSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FDako7U0FDQSxJQUFJLENBQUMsRUFBRSxDQUFDLFFBQVEsQ0FBQztBQUN0QixDQUFDO0FBRUQsTUFBTSxVQUFVLFVBQVUsQ0FBQyxPQUFrQjtJQUMzQyxJQUFJLENBQUMsT0FBTyxFQUFFLE1BQU07UUFBRSxPQUFPLEVBQUUsQ0FBQztJQUNoQyxPQUFPLGlDQUFpQyxPQUFPO1NBQzVDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsU0FBUyxNQUFNLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQztTQUMvQyxJQUFJLENBQUMsRUFBRSxDQUFDLFdBQVcsQ0FBQztBQUN6QixDQUFDO0FBRUQsK0VBQStFO0FBQy9FLDRFQUE0RTtBQUM1RSw2Q0FBNkM7QUFDN0MsTUFBTSxVQUFVLGdCQUFnQixDQUFDLEtBQTBDO0lBQ3pFLE9BQU8seUVBQXlFLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLHFPQUFxTyxNQUFNLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxnVUFBZ1UsQ0FBQztBQUNqcUIsQ0FBQztBQVNELDZFQUE2RTtBQUM3RSx1RUFBdUU7QUFDdkUsTUFBTSxVQUFVLFdBQVcsQ0FBQyxLQUFhLEVBQUUsS0FBbUI7SUFDNUQsT0FBVSxLQUFLLEtBQUssUUFBUTtRQUN4QixDQUFDLENBQUMsb1RBQW9UO1FBQ3RULENBQUMsQ0FBQyxLQUFLLEtBQUssT0FBTztZQUNqQixDQUFDLENBQUMsNkhBQTZILEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLDBhQUEwYSxDQUFDLENBQUMsQ0FBQyxrSEFBa0gsRUFBRTtZQUNsckIsQ0FBQyxDQUFDLEtBQUssS0FBSyxRQUFRO2dCQUNsQixDQUFDLENBQUMsT0FBTyxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxtQkFBbUIsUUFBUSxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLCtEQUErRCxDQUFDLENBQUMsQ0FBQyx3REFBd0QsR0FBRyxLQUFLLENBQUMscUJBQXFCLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsbUZBQW1GLENBQUMsQ0FBQyxDQUFDLHFFQUFxRSxFQUFFO2dCQUNsYyxDQUFDLENBQUMsNEVBQTRFLE1BQU0sQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLDBJQUEwSSxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDLENBQUMsaUNBQWlDLDJFQUEyRSxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLG1FQUFtRSxpREFBaUQsQ0FBQztBQUNsakIsQ0FBQztBQUVELGdGQUFnRjtBQUNoRixpRkFBaUY7QUFDakYsK0VBQStFO0FBQy9FLGdGQUFnRjtBQUNoRixNQUFNLFVBQVUsWUFBWSxDQUFDLE1BQWM7SUFDekMsT0FBTyxvR0FBb0csTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUM7QUFDbkksQ0FBQyJ9
|