bump package version to 1.5.0
[squeep-authentication-module] / lib / template / settings-html.js
1 'use strict';
2
3 /* eslint-disable no-unused-vars */
4
5 const { TemplateHelper: th } = require('@squeep/html-template-helper');
6 const { sessionNavLinks } = require('./helpers');
7 const { TOTP } = require('@squeep/totp');
8
9 /**
10 * @typedef {object} Context
11 * @property {string=} otpConfirmBox encrypted otp state
12 * @property {string=} otpConfirmKey otp key to confirm adding to identifier
13 * @property {string=} authenticationId identifier
14 */
15
16 /**
17 * @alias {object} HtmlOptions
18 */
19
20 /**
21 * @typedef {import('../session-manager').AppTemplateCallback} AppTemplateCallback
22 */
23
24 /**
25 * Render password update section.
26 * @param {Context} ctx context
27 * @param {HtmlOptions} htmlOptions options
28 * @returns {string} section
29 */
30 function updatePasswordSection(ctx, htmlOptions) {
31 return `\t\t\t<section class="settings-update-password">
32 \t\t\t\t<h2>Password</h2>
33 \t\t\t\t<form method="POST">
34 \t\t\t\t\t<fieldset>
35 \t\t\t\t\t\t<legend>Update Password</legend>
36 \t\t\t\t\t\t<label for="credential-current">Current Password:</label>
37 \t\t\t\t\t\t<input type="password" id="credential-current" name="credential-current" value="">
38 \t\t\t\t\t\t<br>
39 \t\t\t\t\t\t<label for="credential-new">New Password:</label>
40 \t\t\t\t\t\t<input type="password" id="credential-new" name="credential-new" value="">
41 \t\t\t\t\t\t<br>
42 \t\t\t\t\t\t<label for="credential-new-2">Confirm New Password:</label>
43 \t\t\t\t\t\t<input type="password" id="credential-new-2" name="credential-new-2" value="">
44 \t\t\t\t\t\t<br>
45 \t\t\t\t\t\t<button type="submit" name="credential" value="update">Update</button>
46 \t\t\t\t\t</fieldset>
47 \t\t\t\t</form>
48 \t\t\t</section>`;
49 }
50
51
52 /**
53 *
54 * @param {Context} ctx context
55 * @param {HtmlOptions} htmlOptions options
56 * @returns {string} otp enable section
57 */
58 function enableOTPSection(ctx, htmlOptions) {
59 return `\t\t\t<section class="settings-otp">
60 \t\t\t\t<h2>OTP 2FA</h2>
61 \t\t\t\t<form method="POST">
62 \t\t\t\t\t<fieldset>
63 \t\t\t\t\t\t<legend>Enable OTP</legend>
64 \t\t\t\t\t\t<button type="submit" name="otp" value="enable">Enable OTP</button>
65 \t\t\t\t\t</fieldset>
66 \t\t\t\t</form>
67 \t\t\t</section>`;
68 }
69
70
71 /**
72 *
73 * @param {Context} ctx context
74 * @param {htmlOptions} htmlOptions options
75 * @returns {string} otp confirm section
76 */
77 function confirmOTPSection(ctx, htmlOptions) {
78 const { secret, svg, uri } = TOTP.createKeySVG({
79 accountname: ctx.authenticationId,
80 }, ctx.otpConfirmKey, 'base32');
81 return `\t\t\t<section class="settings-otp">
82 \t\t\t\t<h2>OTP 2FA</h2>
83 \t\t\t\t<form method="POST">
84 \t\t\t\t\t<fieldset>
85 \t\t\t\t\t<legend>Confirm OTP Key</legend>
86 \t\t\t\t\t\t<div>
87 \t\t\t\t\t\t\t<details>
88 \t\t\t\t\t\t\t\t<summary>Show Key</summary>
89 \t\t\t\t\t\t\t\tOTP Key (base32): <code>${secret}</code>
90 \t\t\t\t\t\t\t\t<div>
91 \t\t\t\t\t\t\t\t\tURI: <code>${uri}</code>
92 \t\t\t\t\t\t\t\t</div>
93 \t\t\t\t\t\t\t</details>
94 \t\t\t\t\t\t</div>
95 \t\t\t\t\t\t<div class="otp-key-qr">
96 ${svg}
97 \t\t\t\t\t\t</div>
98 \t\t\t\t\t\t<br>
99 \t\t\t\t\t\t<label for="otp-token">Enter OTP token to enable:</label>
100 \t\t\t\t\t\t<input id="otp-token" name="otp-token" type="text" value="">
101 \t\t\t\t\t\t<br>
102 \t\t\t\t\t\t<input type="hidden" name="otp-box" value="${ctx.otpConfirmBox}">
103 \t\t\t\t\t\t<button type="submit" name="otp" value="confirm">Confirm OTP</button>
104 \t\t\t\t\t</fieldset>
105 \t\t\t\t</form>
106 \t\t\t</section>`;
107 }
108
109
110 /**
111 *
112 * @param {Context} ctx context
113 * @param {HtmlOptions} htmlOptions options
114 * @returns {string} disable otp section
115 */
116 function disableOTPSection(ctx, htmlOptions) {
117 return `\t\t\t<section class="settings-otp">
118 \t\t\t\t<h2>OTP 2FA</h2>
119 \t\t\t\t<p>OTP is currrently enabled. It may be removed here.</p>
120 \t\t\t\t<form method="POST">
121 \t\t\t\t\t<button type="submit" name="otp" value="disable">Disable OTP</button>
122 \t\t\t\t</form>
123 \t\t\t</section>`;
124 }
125
126
127 /**
128 *
129 * @param {Context} ctx context
130 * @param {HtmlOptions} htmlOptions options
131 * @returns {string} otp section
132 */
133 function OTPSection(ctx, htmlOptions) {
134 const OTPToggle = ctx.otpKey ? disableOTPSection : enableOTPSection;
135 const OTPContent = ctx.otpConfirmBox ? confirmOTPSection : OTPToggle;
136 return '\t\t\t<section class="settings-otp">' +
137 OTPContent(ctx, htmlOptions) +
138 '\t\t\t</section>';
139 }
140
141 /**
142 * Render settings form for managing credential and otp key.
143 * @param {Context} ctx context
144 * @param {object} options options
145 * @param {AppTemplateCallback} appCb function to mogrify htmlOptions
146 * @returns {string} page
147 */
148 module.exports = (ctx, options, appCb = () => {}) => {
149 const pagePathLevel = 1;
150 const htmlOptions = {
151 pageIdentifier: 'account',
152 pageTitle: options.manager.pageTitle,
153 logoUrl: options.manager.logoUrl,
154 footerEntries: options.manager.footerEntries,
155 };
156 appCb(pagePathLevel, ctx, htmlOptions);
157 sessionNavLinks(pagePathLevel, ctx, htmlOptions);
158 const mainContent = [
159 OTPSection(ctx, htmlOptions),
160 updatePasswordSection(ctx, htmlOptions),
161 ];
162
163 return th.htmlPage(pagePathLevel, ctx, htmlOptions, mainContent);
164 };