File

src/auth/api-keys.service.ts

Index

Methods

Constructor

constructor(prisma: PrismaService)
Parameters :
Name Type Optional
prisma PrismaService No

Methods

Async createKey
createKey(orgId: string, userId: string, name: string, permissions: string[], expiresAt?: Date)

Create a new API key. Returns the raw key ONCE -- it can never be retrieved again.

Parameters :
Name Type Optional
orgId string No
userId string No
name string No
permissions string[] No
expiresAt Date Yes
Returns : Promise<literal type>
Async listKeys
listKeys(orgId: string)

List all API keys for an organization (never returns the hashed key).

Parameters :
Name Type Optional
orgId string No
Returns : unknown
Async revokeKey
revokeKey(keyId: string, orgId: string)

Revoke (deactivate) an API key.

Parameters :
Name Type Optional
keyId string No
orgId string No
Returns : unknown
import { Injectable, NotFoundException } from '@nestjs/common';
import * as crypto from 'crypto';
import { PrismaService } from '../prisma/prisma.service';

@Injectable()
export class ApiKeysService {
  constructor(private prisma: PrismaService) {}

  /**
   * Create a new API key. Returns the raw key ONCE -- it can never be retrieved again.
   */
  async createKey(
    orgId: string,
    userId: string,
    name: string,
    permissions: string[],
    expiresAt?: Date,
  ): Promise<{ key: string; record: any }> {
    const raw = 'fc_live_' + crypto.randomBytes(32).toString('hex');
    const hashed = crypto.createHash('sha256').update(raw).digest('hex');
    const prefix = raw.substring(0, 16);

    const record = await this.prisma.apiKey.create({
      data: {
        organizationId: orgId,
        name,
        key: hashed,
        prefix,
        permissions,
        createdById: userId,
        expiresAt: expiresAt || null,
      },
    });

    // Return the raw key once — it cannot be retrieved again
    return { key: raw, record };
  }

  /**
   * List all API keys for an organization (never returns the hashed key).
   */
  async listKeys(orgId: string) {
    return this.prisma.apiKey.findMany({
      where: { organizationId: orgId },
      select: {
        id: true,
        name: true,
        prefix: true,
        permissions: true,
        isActive: true,
        lastUsedAt: true,
        expiresAt: true,
        createdAt: true,
        createdBy: {
          select: {
            id: true,
            firstName: true,
            lastName: true,
            email: true,
          },
        },
      },
      orderBy: { createdAt: 'desc' },
    });
  }

  /**
   * Revoke (deactivate) an API key.
   */
  async revokeKey(keyId: string, orgId: string) {
    const key = await this.prisma.apiKey.findFirst({
      where: { id: keyId, organizationId: orgId },
    });

    if (!key) {
      throw new NotFoundException('API key not found');
    }

    return this.prisma.apiKey.update({
      where: { id: keyId },
      data: { isActive: false },
    });
  }
}

results matching ""

    No results matching ""