File

src/auth/client.service.ts

Index

Properties
Methods

Constructor

constructor(configService: ConfigService, eventEmitter: EventEmitter2)
Parameters :
Name Type Optional
configService ConfigService No
eventEmitter EventEmitter2 No

Methods

findClientById
findClientById(clientId: string)

Find client by ID

Parameters :
Name Type Optional
clientId string No
Returns : Client | null
Private getClients
getClients()

Get clients from configuration

Returns : Client[]
Private loadClients
loadClients()

Load clients from configuration

Returns : Client[]
onApplicationBootstrap
onApplicationBootstrap()
Returns : void
setUpClient
setUpClient(id: string)

Sends an event to set up a client, allowing all other services to listen and react accordingly.

Parameters :
Name Type Optional
id string No
Returns : void
validateClient
validateClient(clientId: string, clientSecret: string)

Validate client credentials (OAuth2 Client Credentials flow) This is the primary authentication method for service integration

Parameters :
Name Type Optional
clientId string No
clientSecret string No
Returns : Client | null

Properties

Private clients
Type : Client[] | null
Default value : null
import { Injectable, OnApplicationBootstrap } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { EventEmitter2 } from '@nestjs/event-emitter';
import { existsSync, mkdirSync, writeFileSync } from 'fs';
import { join } from 'path';
import { TENANT_EVENTS } from './tenant-events';

// Client interface for service integration
export interface Client {
    id: string;
    secret: string;
}

@Injectable()
export class ClientService implements OnApplicationBootstrap {
    private clients: Client[] | null = null;

    constructor(
        private configService: ConfigService,
        private eventEmitter: EventEmitter2,
    ) {}

    onApplicationBootstrap() {
        // were are ignoring clients that are not used anymore for now. Need to implement a proper cleanup mechanism later
        const clients = this.getClients();
        clients.forEach((client) => {
            this.setUpClient(client.id);
        });
    }

    /**
     * Get clients from configuration
     * @returns
     */
    private getClients(): Client[] {
        if (!this.clients) {
            this.clients = this.loadClients();
        }
        return this.clients;
    }

    /**
     * Load clients from configuration
     */
    private loadClients(): Client[] {
        // Default clients for development/testing
        return [
            {
                id: this.configService.getOrThrow<string>('AUTH_CLIENT_ID'),
                secret: this.configService.getOrThrow<string>(
                    'AUTH_CLIENT_SECRET',
                ),
            },
        ];
    }

    /**
     * Validate client credentials (OAuth2 Client Credentials flow)
     * This is the primary authentication method for service integration
     */
    validateClient(clientId: string, clientSecret: string): Client | null {
        const client = this.getClients().find((c) => c.id === clientId);

        if (!client || client.secret !== clientSecret) {
            return null;
        }

        return client;
    }

    /**
     * Find client by ID
     */
    findClientById(clientId: string): Client | null {
        return this.getClients().find((c) => c.id === clientId) || null;
    }

    /**
     * Sends an event to set up a client, allowing all other services to listen and react accordingly.
     * @param id
     */
    setUpClient(id: string) {
        const folder = join(
            this.configService.getOrThrow<string>('FOLDER'),
            id,
        );
        if (!existsSync(folder)) {
            mkdirSync(folder, { recursive: true });
        }

        const displayInfo = [
            {
                name: 'EUDI Wallet dev',
                locale: 'de-DE',
                logo: {
                    uri: '<PUBLIC_URL>/issuer.png',
                    url: '<PUBLIC_URL>/issuer.png',
                },
            },
        ];
        writeFileSync(
            join(folder, 'display.json'),
            JSON.stringify(displayInfo, null, 2),
        );

        this.eventEmitter.emit(TENANT_EVENTS.TENANT_INIT, id);
    }
}

results matching ""

    No results matching ""