X-Git-Url: http://git.squeep.com/?p=squeep-indie-auther;a=blobdiff_plain;f=src%2Ftemplate%2Fadmin-html.js;fp=src%2Ftemplate%2Fadmin-html.js;h=085b95a0ed083eaf4fafa4c131a0496664d37f93;hp=0000000000000000000000000000000000000000;hb=b0103b0d496262c438b40bc20304081dbfe41e73;hpb=8ed81748bce7cea7904cac7225b20a60cafdfc16
diff --git a/src/template/admin-html.js b/src/template/admin-html.js
new file mode 100644
index 0000000..085b95a
--- /dev/null
+++ b/src/template/admin-html.js
@@ -0,0 +1,214 @@
+'use strict';
+
+/**
+ * This renders the administrative view for an account,
+ * allowing for adding profile URIs, custom scope bundles,
+ * and management of issued tokens.
+ */
+
+const th = require('./template-helper');
+
+
+function renderProfileLI(profile) {
+ return `\t
${profile}`;
+}
+
+
+function renderProfileScopeIndicator(profile, scope, selected) {
+ const checked = selected ? ' checked' : '';
+ return `\t\t
+\t\t\t
+\t\t | `;
+}
+
+function renderScopeRow(scope, details, profiles) {
+ return `\t
+${(profiles || []).map((profile) => renderProfileScopeIndicator(profile, scope, details.profiles.includes(profile))).join('\n')}
+\t\t |
+\t\t${details.description} |
+\t\t${details.application} |
+\t\t` +
+ (details.isManuallyAdded ? `
+\t\t\t
+` : '') + `
+\t\t |
+\t
`;
+}
+
+
+function renderProfileHeader(profile) {
+ return `
+\t\t${profile}
+ | `;
+}
+
+
+function scopeIndexTable(scopeIndex, profiles) {
+ return `
+
+\t
+${(profiles || []).map((profile) => renderProfileHeader(profile)).join('\n')}
+\t\tScope |
+\t\tDescription |
+\t\tApplication |
+\t\t |
+\t
+
+
+${Object.entries(scopeIndex).sort(th.scopeCompare).map(([scope, details]) => renderScopeRow(scope, details, profiles)).join('\n')}
+
+
`;
+}
+
+function _tokenType(token) {
+ if (token.resource) {
+ return 'ticket-token';
+ }
+ if (!token.isToken) {
+ return 'profile';
+ }
+ return 'token';
+}
+
+function renderTokenRow(token) {
+ const createdTitle = token.refreshed ? 'Refreshed At' : 'Created At';
+ const createdDate = token.refreshed ? token.refreshed : token.created;
+ return `\t\t
+${_tokenType(token)} |
+\t\t\t${token.clientId} |
+\t\t\t${token.profile} |
+${(token.scopes || []).join(', ')} |
+\t\t\t${token.codeId} |
+\t\t\t${th.timeElement(createdDate, { title: createdTitle })} |
+\t\t\t${th.timeElement(token.expires, { title: 'Expires At' })} |
+\t\t\t${token.isRevoked} |
+${token.resource ? token.resource : ''} |
+\t\t\t` + (
+ token.isRevoked ? '' : `
+\t\t\t\t`) + `
+\t\t\t |
+\t\t
`;
+}
+
+function noTokensRows() {
+ return [`\t\t
+\t\t\t(No active or recent tokens.) |
+\t\t
`];
+}
+
+function tokenTable(tokens) {
+ const tokenRows = tokens?.length ? tokens.map((token) => renderTokenRow(token)) : noTokensRows();
+ return `
+\t
+\t\t
+Type |
+\t\t\tClient Identifier |
+\t\t\tProfile |
+Scopes |
+\t\t\tCode |
+\t\t\tCreated or Refreshed |
+\t\t\tExpires |
+\t\t\tRevoked |
+Resource |
+\t\t\t |
+\t\t
+\t
+\t
+${tokenRows.join('\n')}
+\t
+
`;
+}
+
+function mainContent(ctx) {
+ return `
+\tProfiles
+\t
+\t${(ctx.profilesScopes?.profiles || []).map((p) => renderProfileLI(p)).join('\n')}
+\t
+\t
+
+
+\tScopes
+\t
+\t\t
+\t\t
+
+`;
+}
+
+
+/**
+ *
+ * @param {Object} ctx
+ * @param {Object} ctx.profilesScopes.scopeIndex
+ * @param {String[]} ctx.profilesScopes.profiles
+ * @param {Object[]} ctx.tokens
+ * @param {Object} options
+ * @param {Object} options.manager
+ * @param {String} options.manager.pageTitle
+ * @param {String} options.manager.logoUrl
+ * @param {String[]} options.manager.footerEntries
+ * @returns {String}
+ */
+module.exports = (ctx, options) => {
+ const htmlOptions = {
+ pageTitle: options.manager.pageTitle,
+ logoUrl: options.manager.logoUrl,
+ footerEntries: options.manager.footerEntries,
+ navLinks: [
+ {
+ text: 'Ticket',
+ href: 'ticket',
+ },
+ ],
+ };
+ const content = [
+ mainContent(ctx),
+ ];
+ return th.htmlPage(1, ctx, htmlOptions, content);
+};