chore(release): public-release readiness fixes for 1.1.16

- Fix MIT LICENSE copyright placeholder
- Remove private flag and correct GitHub repository URL in package.json
- Bump version to 1.1.16
- Genericize committed config defaults (example.com/localhost)
- Harden global error handler against information leakage
- Generate random initial password for proxyadmin2 bootstrap account
- Correct docs to describe CONF_SECRETS instead of symlink behavior

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-07-18 22:02:27 -04:00
parent c0e1aa666e
commit d1dd40d60a
9 changed files with 62 additions and 36 deletions
+12 -6
View File
@@ -100,15 +100,21 @@ app.use(async function(req, res, next) {
// Error handler. This is where `next()` will go on error
app.use(async function(err, req, res, next) {
try{
console.error(err.status || res.status, err.name, req.method, req.url);
try{
const status = err.status || 500;
console.error(status, err.name, req.method, req.url);
console.error(err.message);
console.error(err.stack);
if (err.stack) console.error(err.stack);
console.error('=========================================');
res.status(err.status || 500);
res.json({name: err.name, message: err.message, keys: err.keys});
res.status(status);
// Only expose safe, non-internal fields to the client.
const body = { name: err.name, message: err.message };
res.json(body);
}catch(error){
console.log('error in the catch all error fn....', error);
console.error('error in the catch-all error handler', error);
if (!res.headersSent) {
res.status(500).json({ name: 'Error', message: 'Internal server error' });
}
}
});
+8 -8
View File
@@ -6,10 +6,10 @@ module.exports = {
logo: "/static/img/theta42.svg", // shown in the nav; point at your own file under public/ (or an absolute URL) to white-label
userModel: 'redis', // pam, redis, ldap
ldap: {
url: 'ldap://192.168.1.55:389',
bindDN: 'cn=ldapclient service,ou=people,dc=theta42,dc=com',
url: 'ldap://localhost',
bindDN: 'cn=ldapclient service,ou=people,dc=example,dc=com',
bindPassword: '__IN SRECREST FILE__',
searchBase: 'ou=people,dc=theta42,dc=com',
searchBase: 'ou=people,dc=example,dc=com',
userFilter: '(objectClass=inetOrgPerson)',
userNameAttribute: 'uid'
},
@@ -29,11 +29,11 @@ module.exports = {
// redirectUri MUST be registered on the SSO client and match exactly.
oidc: {
enabled: true,
issuer: 'https://sso.theta42.com',
authorizationEndpoint: 'https://sso.theta42.com/oauth/authorize',
tokenEndpoint: 'https://sso.theta42.com/oauth/token',
userinfoEndpoint: 'https://sso.theta42.com/oauth/userinfo',
endSessionEndpoint: 'https://sso.theta42.com/oauth/logout',
issuer: 'https://sso.example.com',
authorizationEndpoint: 'https://sso.example.com/oauth/authorize',
tokenEndpoint: 'https://sso.example.com/oauth/token',
userinfoEndpoint: 'https://sso.example.com/oauth/userinfo',
endSessionEndpoint: 'https://sso.example.com/oauth/logout',
clientId: '__SET_ME__',
// Where the SSO sends the user back. Must be an absolute URL reachable
// by the browser and registered on the SSO client.
+3 -3
View File
@@ -4,10 +4,10 @@
module.exports = {
userModel: 'redis', // pam, redis, ldap
ldap: {
url: 'ldap://192.168.1.55:389',
bindDN: 'cn=ldapclient service,ou=people,dc=theta42,dc=com',
url: 'ldap://localhost',
bindDN: 'cn=ldapclient service,ou=people,dc=example,dc=com',
bindPassword: '__IN SRECREST FILE__',
searchBase: 'ou=people,dc=theta42,dc=com',
searchBase: 'ou=people,dc=example,dc=com',
userFilter: '(objectClass=inetOrgPerson)',
userNameAttribute: 'uid'
},
+14 -5
View File
@@ -90,10 +90,19 @@ User.register();
var defaultUser = 'proxyadmin2'
// Optional: an orchestrator (e.g. theta-env's setup.sh) can set
// auth.localAdminPass in proxy-secrets.js to a generated password so this
// bootstrap account isn't left at the well-known default (username ==
// password == "proxyadmin2"). Only used on first creation -- once the
// account exists this is never read again, so it's safe to leave set.
var defaultPass = (conf.auth && conf.auth.localAdminPass) || defaultUser;
// bootstrap account isn't left at a well-known default. Only used on first
// creation -- once the account exists this is never read again, so it's
// safe to leave set. If unset, a random password is generated and printed
// once; save it from the log or set auth.localAdminPass explicitly.
var defaultPass = (conf.auth && conf.auth.localAdminPass);
if (!defaultPass) {
defaultPass = crypto.randomBytes(16).toString('hex');
console.warn(`====================================================================`);
console.warn(`Bootstrap admin "${defaultUser}" created with random password:`);
console.warn(`${defaultPass}`);
console.warn(`Set auth.localAdminPass in your secrets file to make this deterministic.`);
console.warn(`====================================================================`);
}
try{
let user = await User.get(defaultUser);
}catch(error){
@@ -103,7 +112,7 @@ User.register();
password: defaultPass,
created_by: defaultUser
});
console.log(defaultUser, 'created', user);
console.log(defaultUser, 'created');
}catch(error){
console.error(error)
}
+2 -3
View File
@@ -1,7 +1,6 @@
{
"name": "proxy-api",
"version": "1.1.15",
"private": true,
"version": "1.1.16",
"author": [
{
"name": "William Mantly",
@@ -48,7 +47,7 @@
"license": "MIT",
"repository": {
"type": "git",
"url": "https://git.theta42.com/wmantly/proxy.git"
"url": "https://github.com/theta42/proxy.git"
},
"devDependencies": {
"nodemon": "^3.1.11"