UNPKG

studiocms

Version:

Astro Native CMS for AstroDB. Built from the ground up by the Astro community.

119 lines (113 loc) 4.17 kB
import { cmsEncryptionKey } from 'virtual:studiocms/sdk/env'; import { Effect } from '../../../effect.js'; import { SDKCoreError, StudioCMS_SDK_Error } from '../errors.js'; import { generateJwt, type JwtVerificationResult, verifyJwt } from './lib/jwt-generator.js'; /** * Provides generator utilities for the StudioCMS SDK core, including random ID and password generation, * JWT token creation, and token verification. All generator functions are wrapped in Effect for error handling. * * @remarks * - `generateRandomIDNumber`: Generates a random numeric ID of specified length. * - `generateRandomPassword`: Generates a secure random password containing uppercase, lowercase letters, and digits. * - `generateToken`: Creates a signed JWT for a given user ID, with optional expiration. * - `testToken`: Verifies a JWT token and returns the decoded result. * * @service studiocms/sdk/SDKCore_Generators * @accessors true */ export class SDKCore_Generators extends Effect.Service<SDKCore_Generators>()( 'studiocms/sdk/SDKCore_Generators', { effect: Effect.gen(function* () { /** * Generates a random ID number with the specified length. * * @param length - The length of the random ID number to generate. * @returns A random ID number with the specified length. */ const generateRandomIDNumber = (length: number): Effect.Effect<number, SDKCoreError, never> => Effect.try({ try: () => Math.floor(Math.random() * 10 ** length), catch: (error) => /* v8 ignore start */ new SDKCoreError({ type: 'UNKNOWN', cause: new StudioCMS_SDK_Error(`generateRandomIDNumber Error: ${error}`), }), /* v8 ignore stop */ }); /** * Generates a random password of the specified length. * * @param length - The length of the password to generate. * @returns A randomly generated password string containing uppercase letters, lowercase letters, and digits. */ const generateRandomPassword = (length: number): Effect.Effect<string, SDKCoreError, never> => Effect.try({ try: () => { const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let password = ''; const maxValidValue = Math.floor((2 ** 32 - 1) / characters.length) * characters.length; while (password.length < length) { const n = crypto.getRandomValues(new Uint32Array(1))[0]; if (n < maxValidValue) { password += characters[n % characters.length]; } } return password; }, catch: (error) => /* v8 ignore start */ new SDKCoreError({ type: 'UNKNOWN', cause: new StudioCMS_SDK_Error(`generateRandomPassword Error: ${error}`), }), /* v8 ignore stop */ }); /** * Generates a JSON Web Token (JWT) for a given user ID. * * @param userId - The unique identifier of the user for whom the token is being generated. * @returns A signed JWT string that expires in 3 hours. */ const generateToken = ( userId: string, noExpire?: boolean ): Effect.Effect<string, SDKCoreError, never> => Effect.try({ try: () => generateJwt(cmsEncryptionKey, { userId }, noExpire), catch: (error) => /* v8 ignore start */ new SDKCoreError({ type: 'UNKNOWN', cause: new StudioCMS_SDK_Error(`generateToken Error: ${error}`), }), /* v8 ignore stop */ }); /** * Verifies the provided JWT token using the CMS encryption key. * * @param token - The JWT token to be verified. * @returns The decoded token if verification is successful. * @throws Will throw an error if the token is invalid or verification fails. */ const testToken = ( token: string ): Effect.Effect<JwtVerificationResult, SDKCoreError, never> => Effect.try({ try: () => verifyJwt(token, cmsEncryptionKey), catch: (error) => new SDKCoreError({ type: 'UNKNOWN', cause: new StudioCMS_SDK_Error(`testToken Error: ${error}`), }), }); return { generateRandomIDNumber, generateRandomPassword, generateToken, testToken, }; }), } ) {}