fix: make startup bootstrap production-safe

This commit is contained in:
2026-04-28 15:07:08 +00:00
parent 13a7d5969d
commit 333cbeb221
4 changed files with 47 additions and 5 deletions
+6 -3
View File
@@ -11,7 +11,7 @@ early.stop();
* starts the cloudly instance
*/
const runCli = async () => {
logger.log('info', process.env.SERVEZONE_ENVIRONMENT);
logger.log('info', process.env.SERVEZONE_ENVIRONMENT || '');
const cloudlyInstance = new Cloudly();
logger.log(
@@ -20,8 +20,11 @@ const runCli = async () => {
);
await cloudlyInstance.start();
const demoMod = await import('./00demo/index.js');
demoMod.installDemoData(cloudlyInstance);
if (process.env.SERVEZONE_INSTALL_DEMO_DATA === 'true') {
logger.log('warn', 'SERVEZONE_INSTALL_DEMO_DATA=true: installing destructive demo data');
const demoMod = await import('./00demo/index.js');
await demoMod.installDemoData(cloudlyInstance);
}
};
export { runCli, Cloudly };
+38
View File
@@ -49,6 +49,8 @@ export class CloudlyAuthManager {
this.smartjwtInstance.setKeyPairAsJson(existingJwtKeys);
}
await this.bootstrapInitialAdmin();
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.admin.IReq_Admin_LoginWithUsernameAndPassword>(
'adminLoginWithUsernameAndPassword',
@@ -82,6 +84,42 @@ export class CloudlyAuthManager {
);
}
private async bootstrapInitialAdmin() {
const users = await this.CUser.getInstances({});
const hasHumanUser = users.some((userArg) => userArg.data?.type === 'human');
if (hasHumanUser) {
return;
}
const adminAccount = this.cloudlyRef.config.data.servezoneAdminaccount;
if (!adminAccount) {
throw new Error('SERVEZONE_ADMINACCOUNT is required for first-run Cloudly bootstrap');
}
const separatorIndex = adminAccount.indexOf(':');
if (separatorIndex <= 0 || separatorIndex === adminAccount.length - 1) {
throw new Error('SERVEZONE_ADMINACCOUNT must use username:password format');
}
const username = adminAccount.slice(0, separatorIndex).trim();
const password = adminAccount.slice(separatorIndex + 1);
if (!username || !password) {
throw new Error('SERVEZONE_ADMINACCOUNT must include a non-empty username and password');
}
const user = new this.CUser({
id: await this.CUser.getNewId(),
data: {
type: 'human',
username,
password,
role: 'admin',
},
});
await user.save();
logger.log('success', `created initial admin user ${username}`);
}
public async stop() {}
public validIdentityGuard = new plugins.smartguard.Guard<{