fix(core): update

This commit is contained in:
2024-04-20 12:21:41 +02:00
commit c24262f765
84 changed files with 14340 additions and 0 deletions

View File

@@ -0,0 +1,62 @@
// a secret bundle is a set of secrets ready to be used in a project.
// it bundles secretgroups
import { SecretGroup } from './classes.secretgroup.js';
import * as plugins from '../cloudly.plugins.js';
@plugins.smartdata.Manager()
export class SecretBundle extends plugins.smartdata.SmartDataDbDoc<
SecretBundle,
plugins.servezoneInterfaces.data.ISecretBundle
> {
// STATIC
// INSTANCE
@plugins.smartdata.unI()
public id: string;
@plugins.smartdata.svDb()
public data: plugins.servezoneInterfaces.data.ISecretBundle['data'];
public async getSecretGroups() {
const secretGroups: SecretGroup[] = [];
for (const secretGroupId of this.data.includedSecretGroupIds) {
secretGroups.push(
await SecretGroup.getInstance({
id: secretGroupId,
})
);
}
return secretGroups;
}
/**
* searches the secretGroups for environments and returns them
*/
public async getEnvironments() {
const environments = new Set();
const secretGroups = await this.getSecretGroups();
for (const secretGroup of secretGroups) {
environments.add(secretGroup.data.environments);
}
return Array.from(environments);
}
public async getAuthorizationFromAuthKey(authKeyArg: string) {
const authorization = this.data.authorizations.find((authArg) => {
return authArg.secretAccessKey === authKeyArg;
});
return authorization;
}
public async getKeyValueObjectForEnvironment(environmentArg: string) {
const secretGroups = await this.getSecretGroups();
const returnObject = {};
for (const secretGroup of secretGroups) {
if (!secretGroup.data.environments[environmentArg]) {
continue;
}
returnObject[secretGroup.data.key] = secretGroup.data.environments[environmentArg].value;
}
return returnObject;
}
}

View File

@@ -0,0 +1,21 @@
/**
* a secretgroup is a set of secrets for different environments.
*/
import * as plugins from '../cloudly.plugins.js';
@plugins.smartdata.Manager()
export class SecretGroup extends plugins.smartdata.SmartDataDbDoc<
SecretGroup,
plugins.servezoneInterfaces.data.ISecretGroup
> {
// INSTANCE
/**
* the insatnce id. This should be a random id, except for default
*/
@plugins.smartdata.unI()
id: string;
@plugins.smartdata.svDb()
data: plugins.servezoneInterfaces.data.ISecretGroup['data'];
}

View File

@@ -0,0 +1,156 @@
import * as plugins from '../cloudly.plugins.js';
import * as paths from '../cloudly.paths.js';
import { SecretBundle } from './classes.secretbundle.js';
import { SecretGroup } from './classes.secretgroup.js';
import { logger } from '../cloudly.logging.js';
import type { Cloudly } from '../cloudly.classes.cloudly.js';
/**
* The `ConfigVault` class provides methods for reading and writing configuration data to a file.
* It uses the `TypedServer` and `TypedRouter` classes from the `configvault.plugins.js` module to handle HTTP requests and route them to the appropriate handlers.
*
* @class
*/
export class CloudlySecretManager {
// attached classes
public CSecretBundle = plugins.smartdata.setDefaultManagerForDoc(this, SecretBundle);
public CSecretGroup = plugins.smartdata.setDefaultManagerForDoc(this, SecretGroup);
// INSTANCE
public cloudlyRef: Cloudly;
public projectinfo = new plugins.projectinfo.ProjectinfoNpm(paths.packageDir);
public serviceQenv = new plugins.qenv.Qenv(paths.packageDir, paths.nogitDir);
public typedrouter: plugins.typedrequest.TypedRouter;
get db() {
return this.cloudlyRef.mongodbConnector.smartdataDb;
}
constructor(cloudlyRefArg: Cloudly) {
this.cloudlyRef = cloudlyRefArg;
}
public async start() {
// lets set up a typedrouter
this.typedrouter = new plugins.typedrequest.TypedRouter();
this.cloudlyRef.typedrouter.addTypedRouter(this.typedrouter);
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.secret.IReq_Admin_LoginWithUsernameAndPassword>(
'adminLoginWithUsernameAndPassword',
async (dataArg) => {
let jwt: string;
// console.log(dataArg);
if (dataArg.username !== 'admin' || dataArg.password !== 'password') {
logger.log('warn', 'login failed');
} else {
jwt = await this.cloudlyRef.config.smartjwtInstance.createJWT({
status: 'loggedIn',
});
logger.log('success', 'login successful');
}
return {
jwt,
};
}
)
);
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.secret.IReq_Admin_GetConfigBundlesAndSecretGroups>(
'adminGetConfigBundlesAndSecretGroups',
async (dataArg) => {
dataArg.jwt
const secretBundles = await SecretBundle.getInstances({});
const secretGroups = await SecretGroup.getInstances({});
return {
secretBundles: [
...(await Promise.all(
secretBundles.map((configBundle) => configBundle.createSavableObject())
)),
],
secretGroups: [
...(await Promise.all(
secretGroups.map((secretGroup) => secretGroup.createSavableObject())
)),
],
};
}
)
);
this.typedrouter.addTypedHandler<plugins.servezoneInterfaces.requests.secret.IReq_Admin_CreateConfigBundlesAndSecretGroups>(
new plugins.typedrequest.TypedHandler(
'adminCreateConfigBundlesAndSecretGroups',
async (dataArg) => {
for (const secretGroupObject of dataArg.secretGroups) {
const secretGroup = new SecretGroup();
secretGroup.id = plugins.smartunique.shortId(8);
secretGroup.data = secretGroupObject.data;
await secretGroup.save();
}
return {
ok: true,
};
}
)
);
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.secret.IReq_Admin_DeleteConfigBundlesAndSecretGroups>(
'adminDeleteConfigBundlesAndSecretGroups',
async (dataArg) => {
for (const secretGroupId of dataArg.secretGroupIds) {
const secretGroup = await SecretGroup.getInstance({
id: secretGroupId,
});
await secretGroup.delete();
}
for (const secretBundleId of dataArg.secretBundleIds) {
const configBundle = await SecretBundle.getInstance({
id: secretBundleId,
});
await configBundle.delete();
console.log(`deleted configbundle ${secretBundleId}`);
}
return {
ok: true,
};
}
)
);
// lets add typedrouter routes for accessing the configvailt from apps
this.typedrouter.addTypedHandler(
new plugins.typedrequest.TypedHandler<plugins.servezoneInterfaces.requests.secret.IReq_GetEnvBundle>(
'getEnvBundle',
async (dataArg) => {
const wantedBundle = await SecretBundle.getInstance({
data: {
authorizations: {
// @ts-ignore
$elemMatch: {
secretAccessKey: dataArg.authorization,
},
},
},
});
const authorization = await wantedBundle.getAuthorizationFromAuthKey(
dataArg.authorization
);
return {
envBundle: {
configKeyValueObject: await wantedBundle.getKeyValueObjectForEnvironment(
authorization.environment
),
environment: authorization.environment,
timeSensitive: false,
},
};
}
)
);
}
public async stop() {}
}