Nest Authbeta

Services

Public injectables — what's available via `@Inject()`.

The library exposes its core services as injectables. You can use them from anywhere in your app — they're the same services the library's own controllers call.

AuthService

The main facade for auth flows.

MethodPurpose
signup(payload)Create a user (the same flow /auth/signup triggers)
login(payload)Validate credentials and create a session
refresh(token)Mint a new access token
logout(sessionId) / logoutAll(userId)Revoke sessions
forgotPassword(email) / resetPassword(token, newPassword)Password reset
changePassword(userId, current, next)Authenticated password change

MfaService

MethodPurpose
setupTotp(userId)Generate a TOTP secret and QR code
verifyTotpSetup(userId, secret, code)Confirm and persist a TOTP device
send2fa(userId, method)Trigger an email/SMS code
verify2fa(userId, otp, method, trustDevice?)Verify an MFA challenge
getStatus(userId)MFA-status response (configured methods, recovery codes, devices)
listDevices(userId), removeDevice(userId, deviceId)TOTP device management
toggle(userId, enabled)Enable/disable MFA per user
generateRecoveryCode(userId) / resetMfa(userId, recoveryCode)Recovery

PasswordService

MethodPurpose
hash(password) / verify(password, hash)Argon2 hashing primitives — respect the password.hash/password.verify hooks

UserService

MethodPurpose
findById(id) / findByEmail(email) / findByPhone(phone)Lookups
create(input) / update(id, input) / delete(id)CRUD
setActive(id, isActive)Suspend/reactivate an account

RoleService

Manage roles. A "role" is a named bucket — admin, member, owner — scoped to a guard (web, api, mobile, …). It maps many-to-many to permissions.

MethodPurpose
create(input)Create a role on a guard. input: { name, guard, tenantId?, isSystem?, isActive?, permissions: string[] }
update(id, input)Update name / isActive / permissions. guard, tenantId, isSystem are read-only after creation
delete(id)Delete (rejected if isSystem: true)
findById(id)Fetch a role with its permissions
findOne(where)Lookup by { name, guard, tenantId? }
findAll(query?)List, paginated; filter by guard, tenantId, isActive, etc.
assignPermissions(roleId, permissionIds)Replace the role's permission set
setActive(id, isActive)Toggle without deleting
import { Injectable } from '@nestjs/common';
import { RoleService } from '@ackplus/nest-auth';
 
@Injectable()
export class CustomRolesService {
  constructor(private readonly roles: RoleService) {}
 
  async createPortalRole(name: string, permissions: string[]) {
    return this.roles.create({
      name,
      guard: 'PORTAL',
      isSystem: false,
      isActive: true,
      permissions,
    });
  }
 
  async findPortalRole(name: string) {
    return this.roles.findOne({ name, guard: 'PORTAL' });
  }
}

For end-to-end role assignment (creating the role + attaching it to a user × tenant), see the RBAC concept page and the seeding-roles-and-permissions recipe.

PermissionService

Same shape as RoleService but for the per-action permissions (orders.read, users.delete, …) that roles bundle.

MethodPurpose
create({ name, guard, description?, category? })Create a permission
update(id, { name?, description?, category? })Edit metadata (the guard is read-only)
delete(id)Remove
findById(id) / findOne(where)Lookup
findAll(query?)List, optionally grouped by category
@Injectable()
export class PermissionsBootstrap {
  constructor(private readonly perms: PermissionService) {}
 
  async seedOrders() {
    for (const action of ['read', 'write', 'delete']) {
      await this.perms.create({
        name: `orders.${action}`,
        guard: 'PORTAL',
        category: 'Orders',
        description: `Can ${action} orders`,
      });
    }
  }
}

Permissions are referenced by name in @NestAuthPermissions(...) decorators and in RoleService.create({ permissions: [...] }).

UserAccessService & PlatformAccessService

Manage the actual user × tenant × role[] records. See User Access & Platform Access for the conceptual split.

Method (UserAccess)Purpose
assign({ userId, tenantId, roleNames?, roleIds?, isDefault? })Create/update the membership and roles
assignRoles(userId, tenantId, roleIds)Replace just the roles on an existing membership
findByUser(userId, tenantId?)One or all memberships for a user
setActive(id, isActive)Suspend a user from a single tenant
revoke(userId, tenantId)Remove a user from a tenant (delete the row)
Method (PlatformAccess)Purpose
grant(userId, roleIds)Promote a user to staff (cross-tenant)
revoke(userId)Demote
findByUser(userId)Read

You'll usually call these from your own admin endpoints — there's no public REST surface for them, by design.

TenantService

Tenant lifecycle. Validates slug uniqueness, fires the TenantCreatedEvent / TenantUpdatedEvent / TenantDeletedEvent events.

MethodPurpose
create(input){ name, slug, isActive?, metadata?, description? } — emits TenantCreatedEvent
update(id, input)Patch metadata; emits TenantUpdatedEvent
delete(id)Soft-delete or hard-delete depending on your config; emits TenantDeletedEvent
findById(id) / findBySlug(slug)Lookup
findAll(query?)List with filters, paginated
setActive(id, isActive)Suspend without deleting
@Injectable()
export class OnboardingService {
  constructor(
    private readonly tenants: TenantService,
    private readonly userAccess: UserAccessService,
  ) {}
 
  async createWorkspace(name: string, ownerId: string) {
    const tenant = await this.tenants.create({
      name,
      slug: slugify(name),
      isActive: true,
      metadata: { plan: 'free' },
    });
 
    // Owner gets the admin role on the new tenant (PORTAL guard)
    await this.userAccess.assign({
      userId: ownerId,
      tenantId: tenant.id,
      roleNames: ['admin'],
      isDefault: true,
    });
 
    return tenant;
  }
}

In ISOLATED mode the service handles per-tenant database provisioning automatically — you call create() and the right schema/database is set up behind the scenes. See Multi-tenancy.

SessionManagerService

Direct session-store access. Useful for "list this user's active devices" UIs:

@Auth()
@Get('me/sessions')
async list(@CurrentUser() user: NestAuthUser) {
  return this.sessions.findByUser(user.id);
}
 
@Auth()
@Delete('me/sessions/:id')
async revoke(@Param('id') id: string, @CurrentUser() user: NestAuthUser) {
  return this.sessions.revoke(id, user.id);
}

JwtService

Token sign/verify primitives. Customize signing via the session.jwt.secret config; you rarely need to call this service directly.

AccessKeyService

API key CRUD — see API Keys.

AuditService

Internal sink that calls audit.onEvent. Generally read-only from your code; if you need to write a custom audit event, call audit.write(event).

AuthProviderRegistryService

Read access to the registered auth providers. Use this to render a "sign in with…" button list dynamically:

const providers = registry.list();   // [{ name: 'google', kind: 'oauth' }, …]

AuthConfigService

Frozen snapshot of the resolved module config. Inject this anywhere you need to read the current config:

@Injectable()
class MyService {
  constructor(private readonly auth: AuthConfigService) {}
 
  doStuff() {
    if (this.auth.getOptions().mfa?.required) { … }
  }
}

getOptions() returns the raw IAuthModuleOptions you passed in. getConfig() returns a normalized form with defaults filled in — use whichever is more convenient.

DebugLoggerService

Conditional logger gated by the debug config. Use it from your own services for log lines you only want when debug is on:

this.debugLogger.log('user', `created ${user.id}`);

See Logging & Debugging.

On this page