# Authentication

# Installation

@Module({
  imports: [
    AuthModule.forRoot({
      userPools: {
        [AuthGuardSupport.USER]: {
          type: 'cognito',
          config: {
            jwksUri: `https://cognito-idp.${process.env.COGNITO_REGION}.amazonaws.com/${process.env.COGNITO_USER_POOL_ID}/.well-known/jwks.json`,
          },
          authenticatable: {
            provide: 'ACCOUNT_AUTH_PROVIDER',
            useClass: AccountAuthProvider,
          },
        },
        [AuthGuardSupport.ADMIN]: {
          type: 'cognito',
          config: {
            jwksUri: `https://cognito-idp.${process.env.COGNITO_REGION}.amazonaws.com/${process.env.COGNITO_ADMIN_POOL_ID}/.well-known/jwks.json`,
          },
          authenticatable: {
            provide: 'ADMIN_AUTH_PROVIDER',
            useClass: AdminAuthProvider,
          },
        },
      },
    }),
  ]
})

# Usage

# Provider Account for AuthProvider

@Injectable()
export class AccountAuthProvider implements IAuthenticatable {
  constructor(
    @InjectDataSource('mongodb')
    private dataSource: DataSource,
  ) {}

  async jwt(jwtPayload: { email: string }): Promise<Account> {
    const email = jwtPayload?.email;
    if (!email) {
      throw new BadRequestException('Missing email');
    }
    const account = await this.dataSource
      .getRepository(Account)
      .findOne({ where: { email: email } });

    if (!account) {
      throw new NotFoundException('Missing account');
    }
    return account;
  }
}

# Check authenticate user

...
@UseGuards(AuthGuard(AuthGuardSupport.USER))
@ApiBearerAuth()
@TypedRoute.Put('me')
public async update(
  @TypedBody()
  body: AccountTyped.UpdateRequest,
  @Req() req,
): Promise<Response<Account | null>> {
  const { user } = req;
  if (user === null) {
    throw new NotFoundException('Account not found');
  }

  const data = await this.service.update(body, user);
  return { data };
}
...

@UseGuards(AuthGuard(AuthGuardSupport.ADMIN))
@ApiBearerAuth()
@Get('')
public async all(
  @Query()
  query?: PaginateQueryReq<Account>,
): Promise<Paginated<Account>> {
  return this.service.all(query || {});
}