Index

src/auth/roles/role.enum.ts

allRoles
Type : []
Default value : [ Role.Tenants, Role.IssuanceOffer, Role.Issuances, Role.PresentationRequest, Role.Presentations, Role.Clients, Role.Registrar, ]

List of all roles

src/database/data-source.ts

AppDataSource
Type : unknown
Default value : new DataSource(dataSourceOptions)
commonOptions
Type : Partial<DataSourceOptions>
Default value : { synchronize: false, logging: process.env.DB_LOGGING === "true", migrations: [join(__dirname, "migrations", "*.{ts,js}")], migrationsTableName: "typeorm_migrations", // Entity patterns - TypeORM CLI needs explicit patterns entities: [join(__dirname, "..", "**", "*.entity.{ts,js}")], }
dataSourceOptions
Type : DataSourceOptions
dbType
Type : unknown
Default value : process.env.DB_TYPE as "sqlite" | "postgres" | undefined

src/auth/auth-validation.schema.ts

AUTH_VALIDATION_SCHEMA
Type : Joi.ObjectSchema
Default value : Joi.object({ OIDC: Joi.string() .description("Enable OIDC mode") .meta({ group: "auth", order: 10 }), OIDC_INTERNAL_ISSUER_URL: Joi.string() .uri() .when("OIDC", { is: Joi.exist(), then: Joi.string().default((config) => config.OIDC), otherwise: Joi.optional(), }) .description("Internal issuer URL in OIDC mode") .meta({ group: "auth", order: 20 }), OIDC_CLIENT_ID: Joi.when("OIDC", { is: Joi.exist(), then: Joi.string().required(), otherwise: Joi.optional(), }) .description("Client ID for OIDC") .meta({ group: "auth", order: 25 }), OIDC_CLIENT_SECRET: Joi.when("OIDC", { is: Joi.exist(), then: Joi.string().required(), otherwise: Joi.optional(), }) .description("Client secret for OIDC") .meta({ group: "auth", order: 26 }), OIDC_SUB: Joi.when("OIDC", { is: Joi.exist(), then: Joi.string().default("tenant_id"), otherwise: Joi.optional(), }) .description("Claim to use as subject") .meta({ group: "auth", order: 30 }), OIDC_ALGORITHM: Joi.when("OIDC", { is: Joi.exist(), then: Joi.string().valid("RS256", "PS256", "ES256").default("RS256"), otherwise: Joi.optional(), }) .description("Expected JWT alg") .meta({ group: "auth", order: 40 }), MASTER_SECRET: Joi.when("OIDC", { is: Joi.exist(), then: Joi.string().optional(), otherwise: Joi.string().min(32).required(), }) .description( "Master secret for JWT signing and encryption key derivation - required, minimum 32 characters", ) .meta({ group: "auth", order: 50 }), JWT_ISSUER: Joi.when("OIDC", { is: Joi.exist(), then: Joi.string().optional(), otherwise: Joi.string().default("eudiplo-service"), }) .description("Local JWT issuer") .meta({ group: "auth", order: 60 }), JWT_EXPIRES_IN: Joi.when("OIDC", { is: Joi.exist(), then: Joi.string().optional(), otherwise: Joi.string().default("24h"), }) .description("Local JWT expiration") .meta({ group: "auth", order: 70 }), AUTH_CLIENT_SECRET: Joi.when("OIDC", { is: Joi.exist(), then: Joi.string().optional(), otherwise: Joi.string().required(), }) .description( "Client secret (local auth) - required when OIDC is not enabled", ) .meta({ group: "auth", order: 80 }), AUTH_CLIENT_ID: Joi.when("OIDC", { is: Joi.exist(), then: Joi.string().optional(), otherwise: Joi.string().required(), }) .description( "Client ID (local auth) - required when OIDC is not enabled", ) .meta({ group: "auth", order: 90 }), }).unknown(true)

src/shared/utils/config-printer/validation.schema.ts

BASE_VALIDATION_SCHEMA
Type : unknown
Default value : Joi.object({ FOLDER: Joi.string() .default("../../tmp") .description("Root working folder for temp files") .meta({ group: "general", order: 10 }), GRAFANA_URL: Joi.string() .uri({ scheme: ["http", "https"] }) .optional() .allow("") .description( "Base URL of the Grafana instance for deep linking from the dashboard UI", ) .meta({ group: "observability", order: 10 }), GRAFANA_DATASOURCE_TEMPO_UID: Joi.string() .default("tempo") .description("UID of the Tempo data source in Grafana") .meta({ group: "observability", order: 20 }), GRAFANA_DATASOURCE_LOKI_UID: Joi.string() .default("loki") .description("UID of the Loki data source in Grafana") .meta({ group: "observability", order: 30 }), }).unknown(true)

Validation schema for base configuration

src/auth/client/adapters/internal-clients.service.ts

BCRYPT_ROUNDS
Type : number
Default value : 10

src/auth/client/client.provider.ts

CLIENTS_PROVIDER
Type : string
Default value : "CLIENTS_PROVIDER"

src/shared/utils/config-printer/config-validation.schema.ts

CONFIG_VALIDATION_SCHEMA
Type : unknown
Default value : Joi.object({ CONFIG_IMPORT: Joi.boolean() .default(false) .description("Run one-off config import on startup") .meta({ group: "config", order: 10 }), CONFIG_IMPORT_FORCE: Joi.boolean() .default(false) .description("Force overwrite on config import") .meta({ group: "config", order: 20 }), CONFIG_FOLDER: Joi.string() .default(resolve(__dirname + "/../../../../../assets/config")) .description("Path to config import folder") .meta({ group: "config", order: 30 }), CONFIG_VARIABLE_STRICT: Joi.alternatives() .try(Joi.string().valid("abort", "skip", "ignore"), Joi.boolean()) .default("skip") .description("Strict mode for config import.") .meta({ group: "config", order: 40 }), })

Validation schema for configuration

src/shared/utils/mediaType/media-type.decorator.ts

ContentType
Type : unknown
Default value : createParamDecorator( (data: unknown, ctx: ExecutionContext) => { const request = ctx.switchToHttp().getRequest(); return request.headers["accept"] as string | undefined; }, )

Decorator to extract the content type from the request headers. This decorator can be used to determine the media type of the request.

src/shared/utils/logger/logger.factory.ts

createLoggerOptions
Type : unknown
Default value : (configService: ConfigService) => { // Disable pino-http's autoLogging - we handle HTTP logging explicitly const enableHttpLogger = configService.get<boolean>( "LOG_ENABLE_HTTP_LOGGER", false, ); // Check if file logging is enabled const logToFile = configService.get<boolean>("LOG_TO_FILE"); const logFilePath = configService.get<string>("LOG_FILE_PATH"); // Check if OTel is disabled const otelDisabled = configService.get<string>("OTEL_SDK_DISABLED")?.toLowerCase() === "true"; const logLevel = configService.get("LOG_LEVEL", "info"); // Build transport targets array const targets: any[] = [ // Console pretty logging (always enabled) { target: "pino-pretty", level: logLevel, options: { colorize: true, singleLine: false, translateTime: "yyyy-mm-dd HH:MM:ss", ignore: "pid,hostname,req,res,responseTime,context", messageFormat: "{if context}[{context}] {end}{msg}", }, }, ]; // Optional: File logging if (logToFile && logFilePath) { targets.push({ target: "pino/file", level: logLevel, options: { destination: logFilePath, mkdir: true, sync: true, // Use synchronous writes to ensure message order }, }); } // Optional: OpenTelemetry transport (sends logs to OTel Collector → Loki) // This is how pino logs get trace correlation and appear in Grafana/Loki if (!otelDisabled) { targets.push({ target: "pino-opentelemetry-transport", level: logLevel, options: { // Resource attributes must be explicitly passed to the transport // (it doesn't inherit from the OTel SDK automatically) resourceAttributes: { "service.name": configService.get("OTEL_SERVICE_NAME") || "eudiplo-backend", "service.version": configService.get("VERSION") || "unknown", }, }, }); } return { pinoHttp: { level: logLevel, autoLogging: enableHttpLogger, transport: { targets, }, formatters: { log: (object) => { object.hostname = undefined; return object; }, }, customProps: (req: any) => ({ sessionId: req.params?.session, }), serializers: { req: (req: any) => ({ method: req.method, url: req.url, headers: { "user-agent": req.headers["user-agent"], "content-type": req.headers["content-type"], }, sessionId: req.params?.session, tenantId: req.params?.tenantId, }), res: (res: any) => ({ statusCode: res.statusCode, }), }, }, exclude: [{ path: "/session/:sessionId", method: RequestMethod.ALL }], }; }

Factory function for configuring the logger module

Logging targets:

  • Console: pino-pretty for human-readable output
  • File: JSON logs (optional, via LOG_TO_FILE)
  • OpenTelemetry: pino-opentelemetry-transport sends logs to OTel Collector

Trace correlation:

src/crypto/key/crypto-implementation/crypto-validation.schema.ts

CRYPTO_VALIDATION_SCHEMA
Type : unknown
Default value : Joi.object({ CRYPTO_ALG: Joi.string() .valid("ES256") .default("ES256") .description("The signing algorithm to use") .meta({ group: "crypto", order: 10 }), CRYPTO_TOLERANCE: Joi.number() .default(5) .description("Clock tolerance in seconds for JWT verification") .meta({ group: "crypto", order: 20 }), })

src/database/database-validation.schema.ts

DB_VALIDATION_SCHEMA
Type : unknown
Default value : Joi.object({ DB_TYPE: Joi.string() .valid("sqlite", "postgres") .default("sqlite") .description("Database type") .meta({ group: "database", order: 10 }), DB_HOST: Joi.string() .when("DB_TYPE", { is: "sqlite", then: Joi.optional().allow(""), otherwise: Joi.required(), }) .description("Database host") .meta({ group: "database", order: 15 }), DB_PORT: Joi.number() .when("DB_TYPE", { is: "sqlite", then: Joi.optional().allow(""), otherwise: Joi.required(), }) .description("Database port") .meta({ group: "database", order: 20 }), DB_USERNAME: Joi.string() .when("DB_TYPE", { is: "sqlite", then: Joi.optional().allow(""), otherwise: Joi.required(), }) .description("Database username") .meta({ group: "database", order: 30 }), DB_PASSWORD: Joi.string() .when("DB_TYPE", { is: "sqlite", then: Joi.optional().allow(""), otherwise: Joi.required(), }) .description("Database password") .meta({ group: "database", order: 40 }), DB_DATABASE: Joi.string() .when("DB_TYPE", { is: "sqlite", then: Joi.optional().allow(""), otherwise: Joi.required(), }) .description("Database name") .meta({ group: "database", order: 50 }), DB_SYNCHRONIZE: Joi.boolean() .default(true) .description( "Enable TypeORM schema synchronization. Set to false in production after initial setup and rely on migrations instead.", ) .meta({ group: "database", order: 60 }), DB_MIGRATIONS_RUN: Joi.boolean() .default(true) .description("Run pending database migrations automatically on startup") .meta({ group: "database", order: 70 }), })

src/issuer/trust-list/trustlist.service.ts

DEFAULT_LANG
Type : string
Default value : "en"

Default language for trust list entries

src/crypto/key/key-chain.service.ts

ECDSA_P256
Type : object
Default value : { name: "ECDSA", namedCurve: "P-256", hash: "SHA-256" as const, }

src/shared/utils/encryption/encrypted-column.transformer.ts

EncryptedJsonTransformer
Type : ValueTransformer
Default value : { /** * Transform value when writing to database. * Encrypts the JSON value. */ to(value: unknown): string | null { if (value === null || value === undefined) { return null; } return getEncryptionService().encryptJson(value); }, /** * Transform value when reading from database. * Decrypts the encrypted value back to JSON. */ from(value: string | null): unknown { if (value === null || value === undefined) { return null; } const service = getEncryptionService(); // Handle migration: if value is not encrypted, return as-is (parsed JSON) // This allows existing unencrypted data to be read during migration if (!service.isEncrypted(value)) { // Try to parse as JSON (for existing unencrypted data) try { return typeof value === "string" ? JSON.parse(value) : value; } catch { return value; } } return service.decryptJson(value); }, }

TypeORM column transformer for encrypting JSON data at rest. Encrypts on write (to database) and decrypts on read (from database).

Usage:

EncryptedStringTransformer
Type : ValueTransformer
Default value : { /** * Transform value when writing to database. */ to(value: string | null): string | null { if (value === null || value === undefined) { return null; } return getEncryptionService().encrypt(value); }, /** * Transform value when reading from database. */ from(value: string | null): string | null { if (value === null || value === undefined) { return null; } const service = getEncryptionService(); // Handle migration: if value is not encrypted, return as-is if (!service.isEncrypted(value)) { return value; } return service.decrypt(value); }, }

TypeORM column transformer for encrypting string data at rest. Use for non-JSON string values.

Usage:

encryptionServiceInstance
Type : EncryptionService | null
Default value : null

Singleton holder for the encryption service instance. This is necessary because TypeORM transformers don't support dependency injection.

src/shared/utils/encryption/providers/encryption-key-provider.interface.ts

ENCRYPTION_KEY_PROVIDER
Type : string
Default value : "ENCRYPTION_KEY_PROVIDER"

Injection token for the encryption key provider.

src/shared/utils/encryption/encryption-validation.schema.ts

ENCRYPTION_VALIDATION_SCHEMA
Type : unknown
Default value : Joi.object({ ENCRYPTION_KEY_SOURCE: Joi.string() .valid("env", "vault", "aws", "azure") .default("env") .description( "Source for encryption key: env (dev), vault/aws/azure (prod - key only in RAM)", ) .meta({ group: "encryption", order: 10 }), // Vault-related config (reuses VAULT_ADDR from key-validation.schema.ts) VAULT_ENCRYPTION_KEY_PATH: Joi.string() .when("ENCRYPTION_KEY_SOURCE", { is: "vault", then: Joi.optional().default("secret/data/eudiplo/encryption-key"), otherwise: Joi.optional(), }) .description("Path to encryption key in Vault KV secrets engine") .meta({ group: "encryption", order: 20 }), // AWS Secrets Manager config AWS_ENCRYPTION_SECRET_NAME: Joi.string() .when("ENCRYPTION_KEY_SOURCE", { is: "aws", then: Joi.required(), otherwise: Joi.optional(), }) .description("Name of the encryption key secret in AWS Secrets Manager") .meta({ group: "encryption", order: 30 }), AWS_ENCRYPTION_SECRET_KEY: Joi.string() .when("ENCRYPTION_KEY_SOURCE", { is: "aws", then: Joi.optional().default("key"), otherwise: Joi.optional(), }) .description("JSON key within the AWS secret (if secret is JSON)") .meta({ group: "encryption", order: 40 }), // Azure Key Vault config AZURE_KEYVAULT_URL: Joi.string() .uri() .when("ENCRYPTION_KEY_SOURCE", { is: "azure", then: Joi.required(), otherwise: Joi.optional(), }) .description( "Azure Key Vault URL (e.g., https://myvault.vault.azure.net)", ) .meta({ group: "encryption", order: 50 }), AZURE_ENCRYPTION_SECRET_NAME: Joi.string() .when("ENCRYPTION_KEY_SOURCE", { is: "azure", then: Joi.required(), otherwise: Joi.optional(), }) .description("Name of the encryption key secret in Azure Key Vault") .meta({ group: "encryption", order: 60 }), })

Validation schema for encryption key source configuration.

Configures where the encryption key for data at rest is fetched from:

  • env (default): Derived from MASTER_SECRET (development only)
  • vault: Fetched from HashiCorp Vault (production)
  • aws: Fetched from AWS Secrets Manager (production)
  • azure: Fetched from Azure Key Vault (production)

src/storage/storage.types.ts

FILE_STORAGE
Type : unknown
Default value : Symbol("FILE_STORAGE")

src/auth/public.decorator.ts

IS_PUBLIC_KEY
Type : string
Default value : "isPublic"
Public
Type : unknown
Default value : () => SetMetadata(IS_PUBLIC_KEY, true)

src/issuer/issuer-validation.schema.ts

ISSUER_VALIDATION_SCHEMA
Type : unknown
Default value : Joi.object({ PUBLIC_URL: Joi.string() .default("http://localhost:3000") .description("The public URL of the issuer") .meta({ group: "general", order: 10 }), })

src/crypto/key/dto/kms-config.dto.ts

KMS_PROVIDER_TYPES
Type : unknown
Default value : ["db", "vault", "aws-kms"] as const

Supported KMS adapter types.

src/shared/utils/logger/log-validation.schema.ts

LOG_VALIDATION_SCHEMA
Type : unknown
Default value : Joi.object({ LOG_LEVEL: Joi.string() .valid("trace", "debug", "info", "warn", "error", "fatal") .default(process.env.NODE_ENV === "production" ? "warn" : "debug") .description("Application log level") .meta({ group: "log", order: 10 }), LOG_ENABLE_HTTP_LOGGER: Joi.boolean() .default(false) .description("Enable HTTP request logging") .meta({ group: "log", order: 20 }), LOG_ENABLE_SESSION_LOGGER: Joi.boolean() .default(false) .description("Enable session flow logging") .meta({ group: "log", order: 30 }), LOG_SESSION_STORE: Joi.string() .valid("off", "errors", "all", "verbose") .default("off") .description( "Controls whether session log entries are persisted to the database. " + "'off' disables storage, 'errors' stores only warn/error entries, " + "'all' stores everything, 'verbose' stores everything including full request/response bodies and error stacks.", ) .meta({ group: "log", order: 35 }), LOG_DEBUG_MODE: Joi.boolean() .default(false) .description("Enable verbose debug logs") .meta({ group: "log", order: 40 }), LOG_FORMAT: Joi.string() .valid("json", "pretty") .default(process.env.NODE_ENV === "production" ? "json" : "pretty") .description("Log output format") .meta({ group: "log", order: 50 }), LOG_TO_FILE: Joi.boolean() .default(false) .description("Enable logging to file in addition to console") .meta({ group: "log", order: 60 }), LOG_FILE_PATH: Joi.string() .default("./logs/session.log") .description("File path for log output when LOG_TO_FILE is enabled") .meta({ group: "log", order: 70 }), })

Validation schema for logging configuration

src/verifier/presentations/mdoc-context.ts

mdocContext
Type : MdocContext
Default value : { crypto: { digest: async ({ digestAlgorithm, bytes }) => { const digest = await webCrypto.subtle.digest( digestAlgorithm, toBuffer(bytes), ); return new Uint8Array(digest); }, random: (length: number) => { return webCrypto.getRandomValues(new Uint8Array(length)); }, calculateEphemeralMacKey: async (input) => { const { privateKey, publicKey, sessionTranscriptBytes, info } = input; const ikm = p256 .getSharedSecret(privateKey, publicKey, true) .slice(1); const salt = new Uint8Array( await webCrypto.subtle.digest( "SHA-256", toBuffer(sessionTranscriptBytes), ), ); const infoAsBytes = stringToBytes(info); const digest = "sha256"; const result = await hkdf(digest, ikm, salt, infoAsBytes, 32); return CoseKey.create({ keyOps: [KeyOps.Sign, KeyOps.Verify], keyType: KeyType.Oct, k: result, algorithm: MacAlgorithm.HS256, }); }, }, cose: { mac0: { sign: (input) => { const { key, toBeAuthenticated } = input; return hmac(sha256, key.privateKey, toBeAuthenticated); }, verify: (input) => { const { mac0, key } = input; if (!mac0.tag) { throw new Error("tag is required for mac0 verification"); } return ( mac0.tag === hmac(sha256, key.privateKey, mac0.toBeAuthenticated) ); }, }, sign1: { sign: (input) => { const { key, toBeSigned } = input; return p256.sign(toBeSigned, key.privateKey, { format: "compact", }); }, verify: (input) => { const { sign1, key } = input; const { toBeSigned, signature } = sign1; if (!signature) { throw new Error( "signature is required for sign1 verification", ); } // lowS is needed after upgrade of @noble/curves to keep existing tests passing const res = p256.verify(signature, toBeSigned, key.publicKey, { lowS: false, }); return res; }, }, }, x509: { getIssuerNameField: (input: { certificate: Uint8Array; field: string; }) => { const certificate = new X509Certificate( toBuffer(input.certificate), ); return certificate.issuerName.getField(input.field); }, getPublicKey: async (input: { certificate: Uint8Array; alg: string; }) => { const certificate = new X509Certificate( toBuffer(input.certificate), ); const key = await importX509(certificate.toString(), input.alg, { extractable: true, }); return CoseKey.fromJwk( (await exportJWK(key)) as unknown as Record<string, unknown>, ); }, // NOTE: Certificate chain validation is handled by CredentialChainValidationService // in the verifier layer (MdocverifierService). This method is kept as a no-op to satisfy // the MdocContext interface, but chain validation is disabled via disableCertificateChainValidation // option when calling Verifier.verifyDeviceResponse(). verifyCertificateChain: async (_input: { trustedCertificates: Array<Uint8Array>; x5chain: Array<Uint8Array>; now?: Date; }) => { // No-op: chain validation is handled separately by CredentialChainValidationService }, getCertificateData: async (input: { certificate: Uint8Array }) => { const certificate = new X509Certificate( toBuffer(input.certificate), ); const thumbprint = await certificate.getThumbprint(); const thumbprintHex = hex.encode(new Uint8Array(thumbprint)); return { issuerName: certificate.issuerName.toString(), subjectName: certificate.subjectName.toString(), pem: certificate.toString(), serialNumber: certificate.serialNumber, thumbprint: thumbprintHex, notBefore: certificate.notBefore, notAfter: certificate.notAfter, }; }, }, }
webCrypto
Type : unknown
Default value : globalThis.crypto

src/storage/files.service.ts

MIME_TYPES
Type : Record<string, string>
Default value : { ".png": "image/png", ".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".gif": "image/gif", ".svg": "image/svg+xml", ".webp": "image/webp", ".ico": "image/x-icon", ".bmp": "image/bmp", }

src/issuer/configuration/credentials/types/credential-config-types.ts

MSO_MDOC_FORMAT
Type : MsoMdocFormatIdentifier
Default value : "mso_mdoc"

Format identifier constants for runtime checks

SD_JWT_DC_FORMAT
Type : unknown
Default value : "dc+sd-jwt" as const

src/tracing.ts

otelSDK
Type : unknown
Default value : new NodeSDK({ resource: resourceFromAttributes({ [ATTR_SERVICE_NAME]: process.env.OTEL_SERVICE_NAME || "eudiplo-backend", [ATTR_SERVICE_VERSION]: process.env.VERSION || "unknown", }), traceExporter: new OTLPTraceExporter(), metricReader: new PeriodicExportingMetricReader({ exporter: new OTLPMetricExporter(), exportIntervalMillis: 30_000, }), logRecordProcessors: [new BatchLogRecordProcessor(new OTLPLogExporter())], instrumentations: [ getNodeAutoInstrumentations({ // fs instrumentation is very noisy and adds little value "@opentelemetry/instrumentation-fs": { enabled: false }, // Enable HTTP metrics (server request duration, etc.) "@opentelemetry/instrumentation-http": { enabled: true, }, }), ], })

OpenTelemetry SDK bootstrap — must be started BEFORE NestJS initializes.

All three signals (metrics, traces, logs) are exported via OTLP to an OpenTelemetry Collector. Configure the collector endpoint via:

OTEL_EXPORTER_OTLP_ENDPOINT (default: http://localhost:4318)

To disable OTel entirely (e.g. local dev without collector), set:

OTEL_SDK_DISABLED=true

src/main.ts

PROTOCOL_ROUTE_EXCLUSIONS
Type : literal type[]
Default value : [ // Infrastructure { path: "/", method: RequestMethod.GET }, { path: "health", method: RequestMethod.ALL }, // OAuth2 & Discovery { path: "oauth2/{*path}", method: RequestMethod.ALL }, { path: ".well-known/{*path}", method: RequestMethod.ALL }, // OID4VCI Protocol { path: "issuers/:tenantId/vci/{*path}", method: RequestMethod.ALL }, { path: "issuers/:tenantId/authorize", method: RequestMethod.ALL }, { path: "issuers/:tenantId/authorize/{*path}", method: RequestMethod.ALL }, { path: "issuers/:tenantId/credentials-metadata/{*path}", method: RequestMethod.ALL, }, { path: "issuers/:tenantId/chained-as/{*path}", method: RequestMethod.ALL }, // OID4VP Protocol { path: "presentations/:sessionId/oid4vp", method: RequestMethod.ALL }, { path: "presentations/:sessionId/oid4vp/{*path}", method: RequestMethod.ALL, }, // Public Status & Trust Lists { path: "issuers/:tenantId/status-management/{*path}", method: RequestMethod.ALL, }, { path: "issuers/:tenantId/trust-list/{*path}", method: RequestMethod.ALL }, // Public Storage (credential images, logos) { path: "storage/:key", method: RequestMethod.GET }, ]

Protocol routes excluded from the /api global prefix. These are wallet-facing and infrastructure endpoints that must remain at the root path for protocol compliance and discoverability.

src/registrar/registrar-validation.schema.ts

REGISTRAR_VALIDATION_SCHEMA
Type : unknown
Default value : Joi.object({ REGISTRAR_URL: Joi.string() .description("The URL of the registrar") .meta({ group: "registrar", order: 10 }), REGISTRAR_OIDC_URL: Joi.string() .when("REGISTRAR_URL", { is: Joi.exist(), then: Joi.required(), }) .description("The OIDC URL of the registrar") .meta({ group: "registrar", order: 20 }), REGISTRAR_OIDC_CLIENT_ID: Joi.string() .when("REGISTRAR_URL", { is: Joi.exist(), then: Joi.required(), }) .description("The OIDC client ID of the registrar") .meta({ group: "registrar", order: 30 }), REGISTRAR_OIDC_CLIENT_SECRET: Joi.string() .when("REGISTRAR_URL", { is: Joi.exist(), then: Joi.required(), }) .description("The OIDC client secret of the registrar") .meta({ group: "registrar", order: 40 }), })

Validation schema for the registrar module. Defines the required environment variables and their types.

src/auth/roles/roles.decorator.ts

Roles
Type : unknown
Default value : (...roles: Role[]) => SetMetadata(ROLES_KEY, roles)
ROLES_KEY
Type : string
Default value : "roles"

src/shared/trust/types.ts

ServiceTypeIdentifiers
Type : unknown
Default value : { EaaIssuance: "http://uri.etsi.org/19602/SvcType/EAA/Issuance", EaaRevocation: "http://uri.etsi.org/19602/SvcType/EAA/Revocation", /** Wallet provider service type for wallet attestation validation */ WalletProvider: "http://uri.etsi.org/19602/SvcType/WalletProvider", } as const

Well-known service type identifiers from ETSI TS 119 602

src/session/session-events.service.ts

SESSION_STATUS_CHANGED
Type : string
Default value : "session.status.changed"

src/session/session-validation.schema.ts

SESSION_VALIDATION_SCHEMA
Type : unknown
Default value : Joi.object({ SESSION_TIDY_UP_INTERVAL: Joi.number() .default(60 * 60) .description("Interval in seconds to run session tidy up") .meta({ group: "session", order: 10 }), SESSION_TTL: Joi.number() .default(24 * 60 * 60) .description( "Default time to live for sessions in seconds. Can be overridden per tenant.", ) .meta({ group: "session", order: 20 }), SESSION_CLEANUP_MODE: Joi.string() .valid("full", "anonymize") .default("full") .description( "Default cleanup mode when sessions expire. 'full' deletes the entire session, 'anonymize' keeps metadata but removes personal data. Can be overridden per tenant.", ) .meta({ group: "session", order: 30 }), })

Module for managing user sessions.

src/issuer/lifecycle/status/status-list-validation.schema.ts

STATUS_LIST_VALIDATION_SCHEMA
Type : unknown
Default value : Joi.object({ STATUS_CAPACITY: Joi.number() .default(10000) .description( "The default capacity of the status list. Can be overridden per tenant.", ) .meta({ group: "status", order: 10 }), STATUS_BITS: Joi.number() .valid(1, 2, 4, 8) .default(1) .description( "The default number of bits used per status entry. Can be overridden per tenant.", ) .meta({ group: "status", order: 20 }), STATUS_TTL: Joi.number() .min(60) .default(3600) .description( "The default TTL in seconds for status list JWTs. Verifiers can cache the JWT until expiration. Can be overridden per tenant.", ) .meta({ group: "status", order: 30 }), STATUS_IMMEDIATE_UPDATE: Joi.boolean() .default(false) .description( "If true, regenerate status list JWT immediately on every status change. If false (default), use lazy regeneration when TTL expires. Can be overridden per tenant.", ) .meta({ group: "status", order: 40 }), STATUS_ENABLE_AGGREGATION: Joi.boolean() .default(true) .description( "If true (default), include aggregation_uri in status list JWTs. This allows relying parties to pre-fetch all status lists for offline validation per RFC draft-ietf-oauth-status-list Section 9. Can be overridden per tenant.", ) .meta({ group: "status", order: 50 }), })

src/storage/storage-validation.schema.ts

STORAGE_VALIDATION_SCHEMA
Type : unknown
Default value : Joi.object({ STORAGE_DRIVER: Joi.string() .valid("local", "s3") .default("local") .description("The storage driver to use") .meta({ group: "storage", order: 10 }), LOCAL_STORAGE_DIR: Joi.string() .when(Joi.ref("STORAGE_DRIVER"), { is: "local", then: Joi.string().default((parent) => join(parent.FOLDER, "uploads"), ), }) .description("The directory to store files in when using local storage") .meta({ group: "storage", order: 20 }), S3_REGION: Joi.string() .when(Joi.ref("STORAGE_DRIVER"), { is: "s3", then: Joi.required(), }) .description("The AWS region for the S3 bucket") .meta({ group: "storage", order: 30 }), S3_BUCKET: Joi.string() .when(Joi.ref("STORAGE_DRIVER"), { is: "s3", then: Joi.required(), }) .description("The name of the S3 bucket") .meta({ group: "storage", order: 40 }), S3_ACCESS_KEY_ID: Joi.string() .when(Joi.ref("STORAGE_DRIVER"), { is: "s3", then: Joi.required(), }) .description("The access key ID for the S3 bucket") .meta({ group: "storage", order: 50 }), S3_SECRET_ACCESS_KEY: Joi.string() .when(Joi.ref("STORAGE_DRIVER"), { is: "s3", then: Joi.required(), }) .description("The secret access key for the S3 bucket") .meta({ group: "storage", order: 60 }), S3_ENDPOINT: Joi.string() .when(Joi.ref("STORAGE_DRIVER"), { is: "s3", then: Joi.optional(), }) .description( "The endpoint URL for the S3 service (for S3-compatible services)", ) .meta({ group: "storage", order: 70 }), S3_FORCE_PATH_STYLE: Joi.boolean() .when(Joi.ref("STORAGE_DRIVER"), { is: "s3", then: Joi.boolean().default(false), }) .description("Whether to force path-style URLs for S3") .meta({ group: "storage", order: 80 }), })

src/shared/utils/buffer.util.ts

toBuffer
Type : unknown
Default value : (bytes: Uint8Array): Uint8Array<ArrayBuffer> => { return new Uint8Array(bytes) as unknown as Uint8Array<ArrayBuffer>; }

Helper to convert Uint8Array to Uint8Array This is needed due to TypeScript version differences where newer TS versions use Uint8Array which is not assignable to BufferSource.

Used primarily for mDOC operations where the

src/auth/token.decorator.ts

Token
Type : unknown
Default value : createParamDecorator( (data: unknown, ctx: ExecutionContext) => { const request = ctx.switchToHttp().getRequest(); return request.user as TokenPayload; // Access the token payload on the request object }, )

Token decorator

src/shared/utils/config-printer/combined.schema.ts

VALIDATION_SCHEMA
Type : unknown
Default value : BASE_VALIDATION_SCHEMA.concat( AUTH_VALIDATION_SCHEMA, ) .concat(DB_VALIDATION_SCHEMA) .concat(CONFIG_VALIDATION_SCHEMA) .concat(LOG_VALIDATION_SCHEMA) .concat(CRYPTO_VALIDATION_SCHEMA) .concat(ISSUER_VALIDATION_SCHEMA) .concat(SESSION_VALIDATION_SCHEMA) .concat(STORAGE_VALIDATION_SCHEMA) .concat(STATUS_LIST_VALIDATION_SCHEMA) .concat(ENCRYPTION_VALIDATION_SCHEMA)

Combined validation schema for the application configuration

results matching ""

    No results matching ""