Clean up footer: fix copyright, move GitHub link out of the nav (#41)

- Copyright was "© <year> <name>" where <name> is conf.name — an
  operator-configurable display name (e.g. whatever CFG_ORG is set
  to), not a real copyright holder. Changed to "© <year> theta42",
  matching the LICENSE file. Also dropped "All rights reserved",
  which contradicts the MIT license this project ships under; added
  an explicit MIT License link instead.
- Moved the GitHub icon link out of the top nav (where it competed
  with actual navigation items) and into the footer, alongside the
  license link and version/build info.
- Deduplicated the identical buildVersion/buildHash/buildYear
  computation that was copy-pasted in both routes/index.js and
  routes/oauth.js into a shared nodejs/utils/build_info.js.

Verified by rendering top+bottom with the real ejs package: no
template errors, GitHub link present exactly once (in the footer,
not the nav), "All rights reserved" gone, MIT License link present.
npm test failures (155) are pre-existing/environmental (no LDAP
server here) — identical failure count with these changes stashed
out.
This commit is contained in:
2026-07-14 20:54:36 -04:00
committed by GitHub
parent 3d3b15b283
commit 3ceeeeeca1
5 changed files with 30 additions and 25 deletions
+2 -7
View File
@@ -2,26 +2,21 @@
const fs = require('fs'); const fs = require('fs');
const path = require('path'); const path = require('path');
const { execSync } = require('child_process');
var express = require('express'); var express = require('express');
var router = express.Router(); var router = express.Router();
const moment = require('moment'); const moment = require('moment');
const {marked} = require('marked'); const {marked} = require('marked');
const {InviteToken, PasswordResetToken} = require('./../models/token'); const {InviteToken, PasswordResetToken} = require('./../models/token');
const conf = require('@simpleworkjs/conf'); const conf = require('@simpleworkjs/conf');
const buildInfo = require('../utils/build_info');
const tosHtml = marked(fs.readFileSync(path.join(__dirname, '../../tos.md'), 'utf8')); const tosHtml = marked(fs.readFileSync(path.join(__dirname, '../../tos.md'), 'utf8'));
const { version: buildVersion } = require('../package.json');
let buildHash = 'unknown';
try { buildHash = execSync('git rev-parse --short HEAD', { cwd: __dirname }).toString().trim(); } catch(_) {}
const values ={ const values ={
title: conf.environment !== 'production' ? `dev` : '', title: conf.environment !== 'production' ? `dev` : '',
titleIcon: conf.environment !== 'production' ? `<i class="fa-brands fa-dev"></i>` : '', titleIcon: conf.environment !== 'production' ? `<i class="fa-brands fa-dev"></i>` : '',
name: conf.name, name: conf.name,
buildVersion, ...buildInfo,
buildHash,
buildYear: new Date().getFullYear(),
} }
// List of front end node modules to be served // List of front end node modules to be served
+2 -8
View File
@@ -1,7 +1,6 @@
'use strict'; 'use strict';
const crypto = require('crypto'); const crypto = require('crypto');
const { execSync } = require('child_process');
const jwt = require('jsonwebtoken'); const jwt = require('jsonwebtoken');
const express = require('express'); const express = require('express');
const conf = require('@simpleworkjs/conf'); const conf = require('@simpleworkjs/conf');
@@ -9,22 +8,17 @@ const { OAuthClient } = require('../models/oauth_client');
const { OAuthCode, OAuthAccessToken, OAuthRefreshToken } = require('../models/oauth_code'); const { OAuthCode, OAuthAccessToken, OAuthRefreshToken } = require('../models/oauth_code');
const { User } = require('../models/user'); const { User } = require('../models/user');
const { Group } = require('../models/group_ldap'); const { Group } = require('../models/group_ldap');
const buildInfo = require('../utils/build_info');
const oauthConf = conf.oauth || {}; const oauthConf = conf.oauth || {};
const issuer = oauthConf.issuer || `http://localhost:${conf.port || 3000}`; const issuer = oauthConf.issuer || `http://localhost:${conf.port || 3000}`;
const jwtSecret = oauthConf.jwtSecret || 'change-me-in-secrets'; const jwtSecret = oauthConf.jwtSecret || 'change-me-in-secrets';
const { version: buildVersion } = require('../package.json');
let buildHash = 'unknown';
try { buildHash = execSync('git rev-parse --short HEAD', { cwd: __dirname }).toString().trim(); } catch(_) {}
const pageLocals = { const pageLocals = {
title: conf.environment !== 'production' ? 'dev' : '', title: conf.environment !== 'production' ? 'dev' : '',
titleIcon: conf.environment !== 'production' ? '<i class="fa-brands fa-dev"></i>' : '', titleIcon: conf.environment !== 'production' ? '<i class="fa-brands fa-dev"></i>' : '',
name: conf.name, name: conf.name,
buildVersion, ...buildInfo,
buildHash,
buildYear: new Date().getFullYear(),
}; };
// --- helpers --- // --- helpers ---
+15
View File
@@ -0,0 +1,15 @@
'use strict';
const { execSync } = require('child_process');
const { version: buildVersion } = require('../package.json');
let buildHash = 'unknown';
try {
buildHash = execSync('git rev-parse --short HEAD', { cwd: __dirname }).toString().trim();
} catch (_) {}
module.exports = {
buildVersion,
buildHash,
buildYear: new Date().getFullYear(),
};
+9 -3
View File
@@ -1,14 +1,20 @@
</div><!-- end spa-shell --> </div><!-- end spa-shell -->
<footer class="py-2 bg-dark text-light mt-4"> <footer class="py-2 bg-dark text-light mt-4">
<div class="container-fluid d-flex justify-content-between align-items-center small"> <div class="container-fluid d-flex flex-wrap justify-content-between align-items-center small gap-2">
<span> <span class="d-flex align-items-center gap-2">
<a href="https://theta42.com" target="_blank"> <a href="https://theta42.com" target="_blank">
<img width="64" src="/static/img/theta42.svg"/> <img width="64" src="/static/img/theta42.svg"/>
</a> </a>
&copy; <%- buildYear %> <%- name %>. All rights reserved. &copy; <%- buildYear %> theta42 &middot;
<a href="https://github.com/theta42/sso-manager-node/blob/master/LICENSE" target="_blank" class="text-light">MIT License</a>
</span> </span>
<span class="d-flex align-items-center gap-3">
<a href="https://github.com/theta42/sso-manager-node" target="_blank" class="text-light text-decoration-none">
<i class="fa-brands fa-github"></i> GitHub
</a>
<a href="/tos" class="text-light text-decoration-none">Terms of Service</a> <a href="/tos" class="text-light text-decoration-none">Terms of Service</a>
</span>
<span>v<%- buildVersion %> (<%- buildHash %>)</span> <span>v<%- buildVersion %> (<%- buildHash %>)</span>
</div> </div>
</footer> </footer>
-5
View File
@@ -86,11 +86,6 @@
Admin Admin
</a> </a>
</li> </li>
<li class="nav-item">
<a class="nav-link" href="https://github.com/theta42/sso-manager-node" target="_blank">
<i class="fa-brands fa-github"></i>
</a>
</li>
</ul> </ul>
<div class="form-inline mt-2 mt-md-0"> <div class="form-inline mt-2 mt-md-0">
<a id="cl-login-button" class="btn btn-outline-danger my-2 my-sm-0" onclick="app.auth.forceLogin()" style="display: none;"> <a id="cl-login-button" class="btn btn-outline-danger my-2 my-sm-0" onclick="app.auth.forceLogin()" style="display: none;">