npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@lafken/auth

v0.10.6

Published

Define Cognito User Pools using TypeScript decorators - simplified authentication infrastructure with Lafken

Readme

@lafken/auth

Define and manage Amazon Cognito User Pools using TypeScript decorators. @lafken/auth lets you configure authentication flows, password policies, user attributes, MFA, identity providers, and Lambda triggers — all from a single resolver configuration.

Installation

npm install @lafken/auth

Getting Started

Configure AuthResolver with your User Pool settings, define attributes with @Attributes, and add Lambda triggers with @AuthExtension:

import { createApp } from '@lafken/main';
import { AuthResolver } from '@lafken/auth/resolver';
import { Attributes, Standard, Custom } from '@lafken/auth/main';
import { AuthExtension, Trigger, Event } from '@lafken/auth/main';

// 1. Define user attributes
@Attributes()
export class UserAttributes {
  @Standard({ required: true })
  email: string;

  @Standard({ required: false })
  phoneNumber: string;

  @Custom({ minLen: 2, maxLen: 50 })
  displayName: string;
}

// 2. Define Lambda triggers
@AuthExtension()
export class AuthTriggers {
  @Trigger({ type: 'preSignUp' })
  validateSignUp(@Event() event: any) {
    return event;
  }
}

// 3. Register in the app
createApp({
  name: 'my-app',
  resolvers: [
    new AuthResolver({
      name: 'app-auth',
      userPool: {
        attributes: UserAttributes,
        selfSignUpEnabled: true,
        signInAliases: ['email'],
        passwordPolicy: {
          minLength: 8,
          requireUppercase: true,
          requireDigits: true,
        },
      },
      userClient: {
        authFlows: ['allow_user_password_auth', 'allow_refresh_token_auth'],
      },
      extensions: [AuthTriggers],
    }),
  ],
});

Features

User Pool

Configure the Cognito User Pool through the userPool option in AuthResolver:

new AuthResolver({
  name: 'customer-auth',
  userPool: {
    selfSignUpEnabled: true,
    signInAliases: ['email', 'phone'],
    usernameAttributes: ['email'],
    autoVerifyAttributes: ['email'],
    signInCaseSensitive: false,
    cognitoPlan: 'essentials',
  },
});

User Pool Options

| Option | Type | Description | | ---------------------- | ------------------------ | ------------------------------------------------------------ | | attributes | ClassResource | Class decorated with @Attributes defining user schema | | selfSignUpEnabled | boolean | Allow users to sign up without admin intervention | | signInAliases | SignInAliases[] | Identifiers for sign-in: 'email', 'phone', 'preferred_username' | | usernameAttributes | string[] | Attributes that can be used as the username | | autoVerifyAttributes | string[] | Attributes to auto-verify during sign-up ('email', 'phone') | | signInCaseSensitive | boolean | Whether sign-in identifiers are case-sensitive | | cognitoPlan | CognitoPlan | Pricing plan: 'lite', 'essentials', 'plus' | | passwordPolicy | PasswordPolicy | Password strength requirements | | accountRecovery | AccountRecovery[] | Recovery methods: 'verified_email', 'verified_phone_number', 'admin_only' | | email | EmailConfig | Email sending configuration (Cognito or SES) | | mfa | Mfa | Multi-factor authentication settings | | invitationMessage | InvitationMessage | Custom message for admin-created users | | userVerification | UserVerification | Verification message and method configuration | | identityProviders | IdentityProvider[] | External identity providers (Google, Facebook, etc.) |

Password Policy

Control password strength requirements:

userPool: {
  passwordPolicy: {
    minLength: 12,
    requireUppercase: true,
    requireLowercase: true,
    requireDigits: true,
    requireSymbols: true,
    validityDays: 90,
  },
}

| Option | Type | Description | | ------------------ | --------- | ---------------------------------------------- | | minLength | number | Minimum password length | | requireUppercase | boolean | Require at least one uppercase letter | | requireLowercase | boolean | Require at least one lowercase letter | | requireDigits | boolean | Require at least one digit | | requireSymbols | boolean | Require at least one special character | | validityDays | number | Number of days before password expires |

User Attributes

Define the User Pool schema using a class decorated with @Attributes. Properties use @Standard for built-in Cognito attributes and @Custom for application-specific fields:

import { Attributes, Standard, Custom } from '@lafken/auth/main';

@Attributes()
export class UserAttributes {
  @Standard({ required: true })
  email: string;

  @Standard({ required: false, mutable: true })
  nickname: string;

  @Custom({ minLen: 2, maxLen: 100 })
  displayName: string;

  @Custom({ min: 0, max: 999 })
  score: number;

  @Custom({ mutable: false })
  isVerified: boolean;
}

Standard Attributes

Predefined Cognito attributes following the OpenID Connect specification. Supported names:

name, familyName, givenName, middleName, nickname, preferredUsername, profile, picture, website, gender, birthdate, zoneInfo, locale, updated_at, address, email, phoneNumber, sub

| Option | Type | Default | Description | | ---------- | --------- | ------- | ------------------------------------------------ | | required | boolean | true | Whether the attribute is required during sign-up | | mutable | boolean | true | Whether the value can be changed after creation |

Custom Attributes

Application-specific fields with type-aware constraints:

| Type | Options | Description | | --------- | ---------------------- | ------------------------------------- | | string | minLen, maxLen | String length constraints | | number | min, max | Numeric range constraints | | boolean | mutable | Mutability only |

All custom attributes default to mutable: true.

MFA (Multi-Factor Authentication)

Configure MFA for the User Pool:

userPool: {
  mfa: {
    status: 'required',
    email: {
      subject: 'Your verification code',
      body: 'Your code is {####}',
    },
    sms: 'Your verification code is {####}',
    opt: true,
  },
}

| Option | Type | Description | | -------- | ------------------------------- | --------------------------------------------------- | | status | 'off' \| 'optional' \| 'required' | MFA enforcement level | | email | { subject, body } | Email-based MFA message template | | sms | string | SMS-based MFA message template | | opt | boolean | Enable TOTP (authenticator app) as an MFA option |

Email Configuration

Configure how Cognito sends verification and notification emails:

// Using the default Cognito email service
userPool: {
  email: {
    from: '[email protected]',
    reply: '[email protected]',
  },
}

// Using Amazon SES
userPool: {
  email: {
    account: 'ses',
    arn: 'arn:aws:ses:us-east-1:123456789:identity/example.com',
    from: '[email protected]',
    configurationSet: 'my-ses-config',
  },
}

Verification & Invitation Messages

Customize messages sent during user verification and admin-created user invitations:

userPool: {
  userVerification: {
    email: {
      subject: 'Verify your account',
      body: 'Click this link to verify: {##Verify##}',
      type: 'link',
    },
    sms: 'Your verification code is {####}',
  },
  invitationMessage: {
    email: {
      subject: 'Welcome to our platform',
      body: 'Your username is {username} and temporary password is {####}',
    },
    sms: 'Your username is {username} and password is {####}',
  },
}

Identity Providers

Configure external identity providers so users can sign in with third-party accounts:

Google

userPool: {
  identityProviders: [
    {
      type: 'google',
      clientId: 'google-client-id',
      clientSecret: 'google-client-secret',
      scopes: ['openid', 'email', 'profile'],
      attributes: {
        email: 'email',
        displayName: 'name',
      },
    },
  ],
}

Facebook

{
  type: 'facebook',
  clientId: 'fb-app-id',
  clientSecret: 'fb-app-secret',
  scopes: ['public_profile', 'email'],
  apiVersion: 'v18.0',
  attributes: {
    email: 'email',
    displayName: 'name',
  },
}

Apple

{
  type: 'apple',
  clientId: 'apple-service-id',
  scopes: ['email', 'name'],
  keyId: 'key-id',
  teamId: 'team-id',
  privateKeyValue: '-----BEGIN PRIVATE KEY-----...',
  attributes: {
    email: 'email',
    displayName: 'first_name',
  },
}

Amazon

{
  type: 'amazon',
  clientId: 'amazon-client-id',
  clientSecret: 'amazon-client-secret',
  scopes: ['profile'],
  attributes: {
    email: 'email',
    displayName: 'name',
  },
}

OIDC (OpenID Connect)

{
  type: 'oidc',
  name: 'my-oidc-provider',
  clientId: 'oidc-client-id',
  clientSecret: 'oidc-client-secret',
  scopes: ['openid', 'email'],
  attributesRequestMethod: 'GET',
  authorizeUrl: 'https://provider.com/authorize',
  tokenUrl: 'https://provider.com/token',
  attributesUrl: 'https://provider.com/userinfo',
  jwksUri: 'https://provider.com/.well-known/jwks.json',
  attributes: {
    email: 'email',
  },
}

Attribute mappings map your @Attributes class properties to the provider's attribute names.

User Pool Client

Configure the Cognito User Pool Client through the userClient option:

new AuthResolver({
  name: 'app-auth',
  userClient: {
    authFlows: ['allow_user_password_auth', 'allow_refresh_token_auth'],
    generateSecret: false,
    preventUserExistenceErrors: true,
    enableTokenRevocation: true,
    validity: {
      accessToken: { type: 'hours', value: 1 },
      idToken: { type: 'hours', value: 1 },
      refreshToken: { type: 'days', value: 30 },
      authSession: 300,
    },
    readAttributes: ['email', 'displayName'],
    writeAttributes: ['displayName', 'nickname'],
  },
});

Auth Flows

| Flow | Description | | ------------------------------- | -------------------------------------------- | | allow_user_password_auth | Username and password authentication | | allow_user_srp_auth | Secure Remote Password authentication | | allow_admin_user_password_auth| Admin-initiated password authentication | | allow_custom_auth | Custom authentication flow | | allow_refresh_token_auth | Token refresh flow | | allow_user_auth | General user authentication |

OAuth Configuration

userClient: {
  oauth: {
    flows: ['code'],
    scopes: ['openid', 'email', 'profile'],
    callbackUrls: ['https://app.example.com/callback'],
    logoutUrls: ['https://app.example.com/logout'],
    defaultRedirectUri: 'https://app.example.com/callback',
  },
}

| Option | Type | Description | | -------------------- | -------------- | ---------------------------------------- | | flows | OAuthFlow[] | 'code', 'implicit', 'client_credentials' | | scopes | string[] | OAuth scopes (e.g. 'openid', 'email', 'profile') | | callbackUrls | string[] | Allowed redirect URLs after sign-in | | logoutUrls | string[] | Allowed redirect URLs after sign-out | | defaultRedirectUri | string | Default redirect URL |

Token Validity

validity: {
  authSession: 300,
  accessToken: { type: 'minutes', value: 60 },
  idToken: { type: 'minutes', value: 60 },
  refreshToken: { type: 'days', value: 30 },
}

accessToken, idToken, and refreshToken accept either a number (in minutes) or a ValidityUnit object with type ('seconds', 'minutes', 'hours', 'days') and value.

Extensions (Lambda Triggers)

Extend Cognito behavior with Lambda triggers. Define an extension class with @AuthExtension and add @Trigger methods for each lifecycle event:

import { AuthExtension, Trigger, Event } from '@lafken/auth/main';

@AuthExtension()
export class AuthTriggers {
  @Trigger({ type: 'preSignUp' })
  validateSignUp(@Event() event: any) {
    // Auto-confirm or reject users
    event.response.autoConfirmUser = true;
    return event;
  }

  @Trigger({ type: 'postConfirmation' })
  onConfirmed(@Event() event: any) {
    // Create user profile in database
    return event;
  }

  @Trigger({ type: 'customMessage' })
  customizeMessage(@Event() event: any) {
    // Customize verification emails
    return event;
  }
}

Register extensions in the resolver:

new AuthResolver({
  name: 'app-auth',
  extensions: [AuthTriggers],
});

Available Trigger Types

| Trigger | Description | | ------------------------------ | --------------------------------------------------- | | preSignUp | Validate or modify sign-up data before registration | | preAuthentication | Run logic before authentication completes | | preTokenGeneration | Customize token claims before token issuance | | preTokenGenerationConfig | Configure token generation settings | | postAuthentication | Run logic after successful authentication | | postConfirmation | Run logic after user account confirmation | | userMigration | Migrate users from an external system on sign-in | | createAuthChallenge | Create a custom authentication challenge | | defineAuthChallenge | Define the flow of custom authentication challenges | | verifyAuthChallengeResponse | Verify the response to a custom challenge | | customMessage | Customize verification and MFA messages | | customEmailSender | Custom email delivery logic | | customSmsSender | Custom SMS delivery logic |

Each trigger method can accept a lambda option for custom Lambda settings:

@Trigger({ type: 'preSignUp', lambda: { memory: 512, timeout: 30 } })
validateSignUp(@Event() event: any) { }

Extending the Auth Stack

Use the extend callback to access underlying CDKTN resources and apply advanced configuration:

new AuthResolver({
  name: 'app-auth',
  extend: ({ userPool, userPoolClient, scope }) => {
    // Add custom domains, resource servers, or any CDKTN construct
  },
});