src/issuer/credentials/credential-config/credential-config.service.ts
Service for managing credential configurations.
Methods |
constructor(credentialConfigRepository: Repository<CredentialConfig>, configService: ConfigService, logger: PinoLogger, cryptoService: CryptoService)
|
||||||||||||||||||||
Constructor for CredentialConfigService.
Parameters :
|
delete | ||||||||||||
delete(tenantId: string, id: string)
|
||||||||||||
Deletes a credential configuration for a given tenant.
Parameters :
Returns :
any
A promise that resolves to the result of the delete operation. |
get | ||||||||
get(tenantId: string)
|
||||||||
Retrieves all credential configurations for a given tenant.
Parameters :
Returns :
any
A promise that resolves to an array of CredentialConfig entities. |
getById |
getById(tenantId: string, id: string)
|
Retrieves a credential configuration by its ID for a given tenant.
Returns :
any
|
Public Async import |
import()
|
Imports the configs
Returns :
any
|
Async onTenantDelete | ||||||
onTenantDelete(tenantId: string)
|
||||||
Parameters :
Returns :
any
|
store | ||||||||||||
store(tenantId: string, config: CredentialConfigCreate)
|
||||||||||||
Stores a credential configuration for a given tenant. If the configuration already exists, it will be overwritten.
Parameters :
Returns :
any
A promise that resolves to the stored CredentialConfig entity. |
import { Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { InjectRepository } from "@nestjs/typeorm";
import { plainToClass } from "class-transformer";
import { validate } from "class-validator";
import { readdirSync, readFileSync } from "fs";
import { PinoLogger } from "nestjs-pino";
import { join } from "path";
import { Repository } from "typeorm";
import { CryptoService } from "../../../crypto/crypto.service";
import { CredentialConfigCreate } from "../dto/credential-config-create.dto";
import { CredentialConfig } from "../entities/credential.entity";
/**
* Service for managing credential configurations.
*/
@Injectable()
export class CredentialConfigService {
/**
* Constructor for CredentialConfigService.
* @param credentialConfigRepository - Repository for CredentialConfig entity.
*/
constructor(
@InjectRepository(CredentialConfig)
private readonly credentialConfigRepository: Repository<CredentialConfig>,
private configService: ConfigService,
private logger: PinoLogger,
private cryptoService: CryptoService,
) {}
/**
* Imports the configs
*/
public async import() {
const configPath = this.configService.getOrThrow("CONFIG_FOLDER");
const subfolder = "issuance/credentials";
const force = this.configService.get<boolean>("CONFIG_IMPORT_FORCE");
if (this.configService.get<boolean>("CONFIG_IMPORT")) {
const tenantFolders = readdirSync(configPath, {
withFileTypes: true,
}).filter((tenant) => tenant.isDirectory());
for (const tenant of tenantFolders) {
let counter = 0;
//iterate over all elements in the folder and import them
const path = join(configPath, tenant.name, subfolder);
const files = readdirSync(path);
for (const file of files) {
try {
const payload = JSON.parse(
readFileSync(join(path, file), "utf8"),
);
const id = file.replace(".json", "");
payload.id = id;
const exists = await this.getById(
tenant.name,
id,
).catch(() => false);
if (exists && !force) {
continue; // Skip if config already exists and force is not set
} else if (exists && force) {
//delete old element so removed elements are not present
await this.credentialConfigRepository.delete({
id,
tenantId: tenant.name,
});
}
// Validate the payload against CredentialConfig
const config = plainToClass(
CredentialConfigCreate,
payload,
);
const validationErrors = await validate(config, {
whitelist: true,
forbidUnknownValues: false, // avoid false positives on plain objects
forbidNonWhitelisted: false,
stopAtFirstError: false,
});
// Check if keyId is provided and if the certificate exists
if (config.keyId) {
console.log(config.keyId);
console.log(tenant.name);
const cert = await this.cryptoService.getCertEntry(
tenant.name,
config.keyId,
);
if (!cert) {
this.logger.error(
{
event: "ValidationError",
file,
tenant: tenant.name,
errors: [
{
property: "keyId",
constraints: {
isDefined:
"Key ID must be defined in the crypto service.",
},
value: config.keyId,
},
],
},
`Validation failed for credentials config ${file} in tenant ${tenant.name}`,
);
continue; // Skip this invalid config
}
(config as CredentialConfig).key = cert;
}
if (validationErrors.length > 0) {
this.logger.error(
{
event: "ValidationError",
file,
tenant: tenant.name,
//we need to extract the constraints because they tell what is wrong, also from the children elements
errors: validationErrors,
},
`Validation failed for credentials config ${file} in tenant ${tenant.name}`,
);
continue; // Skip this invalid config
}
await this.store(tenant.name, config);
counter++;
} catch (e) {
this.logger.error(
{
event: "ImportError",
file,
tenant: tenant.name,
error: e.message,
},
`Failed to import credentials config ${file} in tenant ${tenant.name}`,
);
}
}
this.logger.info(
{
event: "Import",
},
`${counter} credential configs imported for ${tenant.name}`,
);
}
}
}
async onTenantDelete(tenantId: string) {
await this.credentialConfigRepository.delete({ tenantId });
}
/**
* Retrieves all credential configurations for a given tenant.
* @param tenantId - The ID of the tenant.
* @returns A promise that resolves to an array of CredentialConfig entities.
*/
get(tenantId: string) {
return this.credentialConfigRepository.find({
where: { tenantId },
relations: ["key"],
});
}
/**
* Retrieves a credential configuration by its ID for a given tenant.
* @param tenantId
* @param id
* @returns
*/
getById(tenantId: string, id: string) {
return this.credentialConfigRepository.findOneByOrFail({
id,
tenantId,
});
}
/**
* Stores a credential configuration for a given tenant.
* If the configuration already exists, it will be overwritten.
* @param tenantId - The ID of the tenant.
* @param config - The CredentialConfig entity to store.
* @returns A promise that resolves to the stored CredentialConfig entity.
*/
store(tenantId: string, config: CredentialConfigCreate) {
return this.credentialConfigRepository.save({
...config,
tenantId,
});
}
/**
* Deletes a credential configuration for a given tenant.
* @param tenantId - The ID of the tenant.
* @param id - The ID of the CredentialConfig entity to delete.
* @returns A promise that resolves to the result of the delete operation.
*/
delete(tenantId: string, id: string) {
return this.credentialConfigRepository.delete({
id,
tenantId,
});
}
}