@spfn/auth 0.2.0-beta.31 → 0.2.0-beta.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -542,7 +542,7 @@ declare const mainAuthRouter: _spfn_core_route.Router<{
542
542
  id: number;
543
543
  name: string;
544
544
  displayName: string;
545
- category: "auth" | "custom" | "user" | "rbac" | "system" | undefined;
545
+ category: "custom" | "user" | "auth" | "rbac" | "system" | undefined;
546
546
  }[];
547
547
  userId: number;
548
548
  email: string | null;
package/dist/config.d.ts CHANGED
@@ -145,6 +145,36 @@ declare const authEnvSchema: {
145
145
  } & {
146
146
  key: "SPFN_AUTH_ADMIN_PASSWORD";
147
147
  };
148
+ SPFN_AUTH_RESERVED_USERNAMES: {
149
+ description: string;
150
+ required: boolean;
151
+ default: string;
152
+ examples: string[];
153
+ type: "string";
154
+ validator: (value: string) => string;
155
+ } & {
156
+ key: "SPFN_AUTH_RESERVED_USERNAMES";
157
+ };
158
+ SPFN_AUTH_USERNAME_MIN_LENGTH: {
159
+ description: string;
160
+ default: number;
161
+ required: boolean;
162
+ examples: number[];
163
+ type: "number";
164
+ validator: (value: string) => number;
165
+ } & {
166
+ key: "SPFN_AUTH_USERNAME_MIN_LENGTH";
167
+ };
168
+ SPFN_AUTH_USERNAME_MAX_LENGTH: {
169
+ description: string;
170
+ default: number;
171
+ required: boolean;
172
+ examples: number[];
173
+ type: "number";
174
+ validator: (value: string) => number;
175
+ } & {
176
+ key: "SPFN_AUTH_USERNAME_MAX_LENGTH";
177
+ };
148
178
  SPFN_API_URL: {
149
179
  description: string;
150
180
  default: string;
@@ -361,6 +391,36 @@ declare const env: _spfn_core_env.InferEnvType<{
361
391
  } & {
362
392
  key: "SPFN_AUTH_ADMIN_PASSWORD";
363
393
  };
394
+ SPFN_AUTH_RESERVED_USERNAMES: {
395
+ description: string;
396
+ required: boolean;
397
+ default: string;
398
+ examples: string[];
399
+ type: "string";
400
+ validator: (value: string) => string;
401
+ } & {
402
+ key: "SPFN_AUTH_RESERVED_USERNAMES";
403
+ };
404
+ SPFN_AUTH_USERNAME_MIN_LENGTH: {
405
+ description: string;
406
+ default: number;
407
+ required: boolean;
408
+ examples: number[];
409
+ type: "number";
410
+ validator: (value: string) => number;
411
+ } & {
412
+ key: "SPFN_AUTH_USERNAME_MIN_LENGTH";
413
+ };
414
+ SPFN_AUTH_USERNAME_MAX_LENGTH: {
415
+ description: string;
416
+ default: number;
417
+ required: boolean;
418
+ examples: number[];
419
+ type: "number";
420
+ validator: (value: string) => number;
421
+ } & {
422
+ key: "SPFN_AUTH_USERNAME_MAX_LENGTH";
423
+ };
364
424
  SPFN_API_URL: {
365
425
  description: string;
366
426
  default: string;
package/dist/config.js CHANGED
@@ -152,6 +152,36 @@ var authEnvSchema = defineEnvSchema({
152
152
  })
153
153
  },
154
154
  // ============================================================================
155
+ // Username Configuration
156
+ // ============================================================================
157
+ SPFN_AUTH_RESERVED_USERNAMES: {
158
+ ...envString({
159
+ description: "Comma-separated list of reserved usernames that cannot be registered",
160
+ required: false,
161
+ default: "admin,root,system,support,help,moderator,superadmin",
162
+ examples: [
163
+ "admin,root,system,support,help",
164
+ "admin,root,system,support,help,moderator,superadmin,operator"
165
+ ]
166
+ })
167
+ },
168
+ SPFN_AUTH_USERNAME_MIN_LENGTH: {
169
+ ...envNumber({
170
+ description: "Minimum username length",
171
+ default: 3,
172
+ required: false,
173
+ examples: [2, 3, 4]
174
+ })
175
+ },
176
+ SPFN_AUTH_USERNAME_MAX_LENGTH: {
177
+ ...envNumber({
178
+ description: "Maximum username length",
179
+ default: 30,
180
+ required: false,
181
+ examples: [20, 30, 50]
182
+ })
183
+ },
184
+ // ============================================================================
155
185
  // API Configuration
156
186
  // ============================================================================
157
187
  SPFN_API_URL: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config/index.ts","../src/config/schema.ts"],"sourcesContent":["/**\n * Core Package Configuration\n *\n * @example\n * ```typescript\n * import { registry } from '@spfn/core/config';\n *\n * const env = registry.validate();\n * console.log(env.DB_POOL_MAX);\n * ```\n *\n * @module config\n */\n\nimport { createEnvRegistry } from '@spfn/core/env';\nimport { authEnvSchema } from './schema';\n\nexport { authEnvSchema as envSchema } from './schema';\n\n/**\n * Environment registry\n */\nconst registry = createEnvRegistry(authEnvSchema);\nexport const env = registry.validate();","/**\n * Auth Environment Variable Schema\n *\n * Centralized schema definition for all environment variables used in @spfn/auth.\n * This provides type safety, validation, and documentation for Auth configuration.\n *\n * @module config/schema\n */\n\nimport {\n defineEnvSchema,\n envString,\n envNumber,\n createSecureSecretParser,\n createPasswordParser,\n} from '@spfn/core/env';\n\n/**\n * Auth environment variable schema\n *\n * Defines all Auth environment variables with:\n * - Type information\n * - Default values\n * - Validation rules\n * - Documentation\n *\n * @example\n * ```typescript\n * import { authEnvSchema } from '@spfn/auth/config';\n *\n * // Access schema information\n * console.log(authEnvSchema.SPFN_AUTH_SESSION_SECRET.description);\n * console.log(authEnvSchema.SPFN_AUTH_JWT_EXPIRES_IN.default);\n * ```\n */\nexport const authEnvSchema = defineEnvSchema({\n // ============================================================================\n // Session Configuration\n // ============================================================================\n SPFN_AUTH_SESSION_SECRET: {\n ...envString({\n description: 'Session encryption secret (minimum 32 characters for AES-256)',\n required: true,\n fallbackKeys: ['SESSION_SECRET'],\n validator: createSecureSecretParser({\n minLength: 32,\n minUniqueChars: 16,\n minEntropy: 3.5,\n }),\n sensitive: true,\n nextjs: true, // Required for Next.js RSC session validation\n examples: [\n 'my-super-secret-session-key-at-least-32-chars-long',\n 'use-a-cryptographically-secure-random-string-here',\n ],\n }),\n },\n\n SPFN_AUTH_SESSION_TTL: {\n ...envString({\n description: 'Session TTL (time to live) - supports duration strings like \\'7d\\', \\'12h\\', \\'45m\\'',\n default: '7d',\n required: false,\n nextjs: true, // May be needed for session validation in Next.js RSC\n examples: ['7d', '30d', '12h', '45m', '3600'],\n }),\n },\n\n // ============================================================================\n // JWT Configuration\n // ============================================================================\n SPFN_AUTH_JWT_SECRET: {\n ...envString({\n description: 'JWT signing secret for server-signed tokens (legacy mode)',\n default: 'dev-secret-key-change-in-production',\n required: false,\n examples: [\n 'your-jwt-secret-key-here',\n 'use-different-from-session-secret',\n ],\n }),\n },\n\n SPFN_AUTH_JWT_EXPIRES_IN: {\n ...envString({\n description: 'JWT token expiration time (e.g., \\'7d\\', \\'24h\\', \\'1h\\')',\n default: '7d',\n required: false,\n examples: ['7d', '24h', '1h', '30m'],\n }),\n },\n\n // ============================================================================\n // Security Configuration\n // ============================================================================\n SPFN_AUTH_BCRYPT_SALT_ROUNDS: {\n ...envNumber({\n description: 'Bcrypt salt rounds (cost factor, higher = more secure but slower)',\n default: 10,\n required: false,\n examples: [10, 12, 14],\n }),\n key: 'SPFN_AUTH_BCRYPT_SALT_ROUNDS',\n },\n\n SPFN_AUTH_VERIFICATION_TOKEN_SECRET: {\n ...envString({\n description: 'Verification token secret for email verification, password reset, etc.',\n required: true,\n examples: [\n 'your-verification-token-secret',\n 'can-be-different-from-jwt-secret',\n ],\n }),\n },\n\n // ============================================================================\n // Admin Account Configuration\n // ============================================================================\n SPFN_AUTH_ADMIN_ACCOUNTS: {\n ...envString({\n description: 'JSON array of admin accounts (recommended for multiple admins)',\n required: false,\n examples: [\n '[{\"email\":\"admin@example.com\",\"password\":\"secure-pass\",\"role\":\"admin\"}]',\n '[{\"email\":\"super@example.com\",\"password\":\"pass1\",\"role\":\"superadmin\"},{\"email\":\"admin@example.com\",\"password\":\"pass2\",\"role\":\"admin\"}]',\n ],\n }),\n },\n\n SPFN_AUTH_ADMIN_EMAILS: {\n ...envString({\n description: 'Comma-separated list of admin emails (legacy CSV format)',\n required: false,\n examples: [\n 'admin@example.com,user@example.com',\n 'super@example.com,admin@example.com,user@example.com',\n ],\n }),\n },\n\n SPFN_AUTH_ADMIN_PASSWORDS: {\n ...envString({\n description: 'Comma-separated list of admin passwords (legacy CSV format)',\n required: false,\n examples: [\n 'admin-pass,user-pass',\n 'super-pass,admin-pass,user-pass',\n ],\n }),\n },\n\n SPFN_AUTH_ADMIN_ROLES: {\n ...envString({\n description: 'Comma-separated list of admin roles (legacy CSV format)',\n required: false,\n examples: [\n 'admin,user',\n 'superadmin,admin,user',\n ],\n }),\n },\n\n SPFN_AUTH_ADMIN_EMAIL: {\n ...envString({\n description: 'Single admin email (simplest format)',\n required: false,\n examples: ['admin@example.com'],\n }),\n },\n\n SPFN_AUTH_ADMIN_PASSWORD: {\n ...envString({\n description: 'Single admin password (simplest format)',\n required: false,\n validator: createPasswordParser({\n minLength: 8,\n requireUppercase: true,\n requireLowercase: true,\n requireNumber: true,\n requireSpecial: true,\n }),\n sensitive: true,\n examples: ['SecureAdmin123!'],\n }),\n },\n\n // ============================================================================\n // API Configuration\n // ============================================================================\n SPFN_API_URL: {\n ...envString({\n description: 'Internal API URL for server-to-server communication',\n default: 'http://localhost:8790',\n required: false,\n examples: [\n 'https://api.example.com',\n 'http://localhost:8790',\n ],\n }),\n },\n\n NEXT_PUBLIC_SPFN_API_URL: {\n ...envString({\n description: 'Public-facing API URL used for browser-facing redirects (e.g. OAuth callback). Falls back to SPFN_API_URL if not set.',\n required: false,\n examples: [\n 'https://api.example.com',\n 'http://localhost:8790',\n ],\n }),\n },\n\n SPFN_APP_URL: {\n ...envString({\n description: 'Next.js application URL (internal). Used for server-to-server communication.',\n default: 'http://localhost:3000',\n required: false,\n examples: [\n 'https://app.example.com',\n 'http://localhost:3000',\n ],\n }),\n },\n\n NEXT_PUBLIC_SPFN_APP_URL: {\n ...envString({\n description: 'Public-facing Next.js app URL for browser redirects (e.g. OAuth redirect). Falls back to SPFN_APP_URL if not set.',\n required: false,\n examples: [\n 'https://app.example.com',\n 'http://localhost:3000',\n ],\n }),\n },\n\n // ============================================================================\n // OAuth Configuration - Google\n // ============================================================================\n SPFN_AUTH_GOOGLE_CLIENT_ID: {\n ...envString({\n description: 'Google OAuth 2.0 Client ID. When set, Google OAuth routes are automatically enabled.',\n required: false,\n examples: ['123456789-abc123.apps.googleusercontent.com'],\n }),\n },\n\n SPFN_AUTH_GOOGLE_CLIENT_SECRET: {\n ...envString({\n description: 'Google OAuth 2.0 Client Secret',\n required: false,\n sensitive: true,\n examples: ['GOCSPX-abcdefghijklmnop'],\n }),\n },\n\n SPFN_AUTH_GOOGLE_SCOPES: {\n ...envString({\n description: 'Comma-separated Google OAuth scopes. Defaults to \"email,profile\" if not set.',\n required: false,\n examples: [\n 'email,profile',\n 'email,profile,https://www.googleapis.com/auth/gmail.readonly',\n 'email,profile,https://www.googleapis.com/auth/calendar.readonly',\n ],\n }),\n },\n\n SPFN_AUTH_GOOGLE_REDIRECT_URI: {\n ...envString({\n description: 'Google OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_API_URL || SPFN_API_URL}/_auth/oauth/google/callback',\n required: false,\n examples: [\n 'https://api.example.com/_auth/oauth/google/callback',\n 'http://localhost:8790/_auth/oauth/google/callback',\n ],\n }),\n },\n\n SPFN_AUTH_OAUTH_SUCCESS_URL: {\n ...envString({\n description: 'OAuth callback page URL. This page should use OAuthCallback component to finalize session.',\n required: false,\n default: '/auth/callback',\n examples: [\n '/auth/callback',\n 'https://app.example.com/auth/callback',\n ],\n }),\n },\n\n SPFN_AUTH_OAUTH_ERROR_URL: {\n ...envString({\n description: 'URL to redirect after OAuth error. Use {error} placeholder for error message.',\n required: false,\n default: 'http://localhost:3000/auth/error?error={error}',\n examples: [\n 'https://app.example.com/auth/error?error={error}',\n 'http://localhost:3000/auth/error?error={error}',\n ],\n }),\n },\n});"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/config/index.ts","../src/config/schema.ts"],"sourcesContent":["/**\n * Core Package Configuration\n *\n * @example\n * ```typescript\n * import { registry } from '@spfn/core/config';\n *\n * const env = registry.validate();\n * console.log(env.DB_POOL_MAX);\n * ```\n *\n * @module config\n */\n\nimport { createEnvRegistry } from '@spfn/core/env';\nimport { authEnvSchema } from './schema';\n\nexport { authEnvSchema as envSchema } from './schema';\n\n/**\n * Environment registry\n */\nconst registry = createEnvRegistry(authEnvSchema);\nexport const env = registry.validate();","/**\n * Auth Environment Variable Schema\n *\n * Centralized schema definition for all environment variables used in @spfn/auth.\n * This provides type safety, validation, and documentation for Auth configuration.\n *\n * @module config/schema\n */\n\nimport {\n defineEnvSchema,\n envString,\n envNumber,\n createSecureSecretParser,\n createPasswordParser,\n} from '@spfn/core/env';\n\n/**\n * Auth environment variable schema\n *\n * Defines all Auth environment variables with:\n * - Type information\n * - Default values\n * - Validation rules\n * - Documentation\n *\n * @example\n * ```typescript\n * import { authEnvSchema } from '@spfn/auth/config';\n *\n * // Access schema information\n * console.log(authEnvSchema.SPFN_AUTH_SESSION_SECRET.description);\n * console.log(authEnvSchema.SPFN_AUTH_JWT_EXPIRES_IN.default);\n * ```\n */\nexport const authEnvSchema = defineEnvSchema({\n // ============================================================================\n // Session Configuration\n // ============================================================================\n SPFN_AUTH_SESSION_SECRET: {\n ...envString({\n description: 'Session encryption secret (minimum 32 characters for AES-256)',\n required: true,\n fallbackKeys: ['SESSION_SECRET'],\n validator: createSecureSecretParser({\n minLength: 32,\n minUniqueChars: 16,\n minEntropy: 3.5,\n }),\n sensitive: true,\n nextjs: true, // Required for Next.js RSC session validation\n examples: [\n 'my-super-secret-session-key-at-least-32-chars-long',\n 'use-a-cryptographically-secure-random-string-here',\n ],\n }),\n },\n\n SPFN_AUTH_SESSION_TTL: {\n ...envString({\n description: 'Session TTL (time to live) - supports duration strings like \\'7d\\', \\'12h\\', \\'45m\\'',\n default: '7d',\n required: false,\n nextjs: true, // May be needed for session validation in Next.js RSC\n examples: ['7d', '30d', '12h', '45m', '3600'],\n }),\n },\n\n // ============================================================================\n // JWT Configuration\n // ============================================================================\n SPFN_AUTH_JWT_SECRET: {\n ...envString({\n description: 'JWT signing secret for server-signed tokens (legacy mode)',\n default: 'dev-secret-key-change-in-production',\n required: false,\n examples: [\n 'your-jwt-secret-key-here',\n 'use-different-from-session-secret',\n ],\n }),\n },\n\n SPFN_AUTH_JWT_EXPIRES_IN: {\n ...envString({\n description: 'JWT token expiration time (e.g., \\'7d\\', \\'24h\\', \\'1h\\')',\n default: '7d',\n required: false,\n examples: ['7d', '24h', '1h', '30m'],\n }),\n },\n\n // ============================================================================\n // Security Configuration\n // ============================================================================\n SPFN_AUTH_BCRYPT_SALT_ROUNDS: {\n ...envNumber({\n description: 'Bcrypt salt rounds (cost factor, higher = more secure but slower)',\n default: 10,\n required: false,\n examples: [10, 12, 14],\n }),\n key: 'SPFN_AUTH_BCRYPT_SALT_ROUNDS',\n },\n\n SPFN_AUTH_VERIFICATION_TOKEN_SECRET: {\n ...envString({\n description: 'Verification token secret for email verification, password reset, etc.',\n required: true,\n examples: [\n 'your-verification-token-secret',\n 'can-be-different-from-jwt-secret',\n ],\n }),\n },\n\n // ============================================================================\n // Admin Account Configuration\n // ============================================================================\n SPFN_AUTH_ADMIN_ACCOUNTS: {\n ...envString({\n description: 'JSON array of admin accounts (recommended for multiple admins)',\n required: false,\n examples: [\n '[{\"email\":\"admin@example.com\",\"password\":\"secure-pass\",\"role\":\"admin\"}]',\n '[{\"email\":\"super@example.com\",\"password\":\"pass1\",\"role\":\"superadmin\"},{\"email\":\"admin@example.com\",\"password\":\"pass2\",\"role\":\"admin\"}]',\n ],\n }),\n },\n\n SPFN_AUTH_ADMIN_EMAILS: {\n ...envString({\n description: 'Comma-separated list of admin emails (legacy CSV format)',\n required: false,\n examples: [\n 'admin@example.com,user@example.com',\n 'super@example.com,admin@example.com,user@example.com',\n ],\n }),\n },\n\n SPFN_AUTH_ADMIN_PASSWORDS: {\n ...envString({\n description: 'Comma-separated list of admin passwords (legacy CSV format)',\n required: false,\n examples: [\n 'admin-pass,user-pass',\n 'super-pass,admin-pass,user-pass',\n ],\n }),\n },\n\n SPFN_AUTH_ADMIN_ROLES: {\n ...envString({\n description: 'Comma-separated list of admin roles (legacy CSV format)',\n required: false,\n examples: [\n 'admin,user',\n 'superadmin,admin,user',\n ],\n }),\n },\n\n SPFN_AUTH_ADMIN_EMAIL: {\n ...envString({\n description: 'Single admin email (simplest format)',\n required: false,\n examples: ['admin@example.com'],\n }),\n },\n\n SPFN_AUTH_ADMIN_PASSWORD: {\n ...envString({\n description: 'Single admin password (simplest format)',\n required: false,\n validator: createPasswordParser({\n minLength: 8,\n requireUppercase: true,\n requireLowercase: true,\n requireNumber: true,\n requireSpecial: true,\n }),\n sensitive: true,\n examples: ['SecureAdmin123!'],\n }),\n },\n\n // ============================================================================\n // Username Configuration\n // ============================================================================\n SPFN_AUTH_RESERVED_USERNAMES: {\n ...envString({\n description: 'Comma-separated list of reserved usernames that cannot be registered',\n required: false,\n default: 'admin,root,system,support,help,moderator,superadmin',\n examples: [\n 'admin,root,system,support,help',\n 'admin,root,system,support,help,moderator,superadmin,operator',\n ],\n }),\n },\n\n SPFN_AUTH_USERNAME_MIN_LENGTH: {\n ...envNumber({\n description: 'Minimum username length',\n default: 3,\n required: false,\n examples: [2, 3, 4],\n }),\n },\n\n SPFN_AUTH_USERNAME_MAX_LENGTH: {\n ...envNumber({\n description: 'Maximum username length',\n default: 30,\n required: false,\n examples: [20, 30, 50],\n }),\n },\n\n // ============================================================================\n // API Configuration\n // ============================================================================\n SPFN_API_URL: {\n ...envString({\n description: 'Internal API URL for server-to-server communication',\n default: 'http://localhost:8790',\n required: false,\n examples: [\n 'https://api.example.com',\n 'http://localhost:8790',\n ],\n }),\n },\n\n NEXT_PUBLIC_SPFN_API_URL: {\n ...envString({\n description: 'Public-facing API URL used for browser-facing redirects (e.g. OAuth callback). Falls back to SPFN_API_URL if not set.',\n required: false,\n examples: [\n 'https://api.example.com',\n 'http://localhost:8790',\n ],\n }),\n },\n\n SPFN_APP_URL: {\n ...envString({\n description: 'Next.js application URL (internal). Used for server-to-server communication.',\n default: 'http://localhost:3000',\n required: false,\n examples: [\n 'https://app.example.com',\n 'http://localhost:3000',\n ],\n }),\n },\n\n NEXT_PUBLIC_SPFN_APP_URL: {\n ...envString({\n description: 'Public-facing Next.js app URL for browser redirects (e.g. OAuth redirect). Falls back to SPFN_APP_URL if not set.',\n required: false,\n examples: [\n 'https://app.example.com',\n 'http://localhost:3000',\n ],\n }),\n },\n\n // ============================================================================\n // OAuth Configuration - Google\n // ============================================================================\n SPFN_AUTH_GOOGLE_CLIENT_ID: {\n ...envString({\n description: 'Google OAuth 2.0 Client ID. When set, Google OAuth routes are automatically enabled.',\n required: false,\n examples: ['123456789-abc123.apps.googleusercontent.com'],\n }),\n },\n\n SPFN_AUTH_GOOGLE_CLIENT_SECRET: {\n ...envString({\n description: 'Google OAuth 2.0 Client Secret',\n required: false,\n sensitive: true,\n examples: ['GOCSPX-abcdefghijklmnop'],\n }),\n },\n\n SPFN_AUTH_GOOGLE_SCOPES: {\n ...envString({\n description: 'Comma-separated Google OAuth scopes. Defaults to \"email,profile\" if not set.',\n required: false,\n examples: [\n 'email,profile',\n 'email,profile,https://www.googleapis.com/auth/gmail.readonly',\n 'email,profile,https://www.googleapis.com/auth/calendar.readonly',\n ],\n }),\n },\n\n SPFN_AUTH_GOOGLE_REDIRECT_URI: {\n ...envString({\n description: 'Google OAuth callback URL. Defaults to {NEXT_PUBLIC_SPFN_API_URL || SPFN_API_URL}/_auth/oauth/google/callback',\n required: false,\n examples: [\n 'https://api.example.com/_auth/oauth/google/callback',\n 'http://localhost:8790/_auth/oauth/google/callback',\n ],\n }),\n },\n\n SPFN_AUTH_OAUTH_SUCCESS_URL: {\n ...envString({\n description: 'OAuth callback page URL. This page should use OAuthCallback component to finalize session.',\n required: false,\n default: '/auth/callback',\n examples: [\n '/auth/callback',\n 'https://app.example.com/auth/callback',\n ],\n }),\n },\n\n SPFN_AUTH_OAUTH_ERROR_URL: {\n ...envString({\n description: 'URL to redirect after OAuth error. Use {error} placeholder for error message.',\n required: false,\n default: 'http://localhost:3000/auth/error?error={error}',\n examples: [\n 'https://app.example.com/auth/error?error={error}',\n 'http://localhost:3000/auth/error?error={error}',\n ],\n }),\n },\n});"],"mappings":"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","names":[]}
package/dist/errors.d.ts CHANGED
@@ -132,6 +132,18 @@ declare class VerificationTokenTargetMismatchError extends ValidationError {
132
132
  details?: Record<string, any>;
133
133
  });
134
134
  }
135
+ /**
136
+ * Reserved Username Error (400)
137
+ *
138
+ * Thrown when trying to use a reserved/prohibited username
139
+ */
140
+ declare class ReservedUsernameError extends ValidationError {
141
+ constructor(data?: {
142
+ username?: string;
143
+ message?: string;
144
+ details?: Record<string, any>;
145
+ });
146
+ }
135
147
  /**
136
148
  * Username Already Taken Error (409)
137
149
  *
@@ -189,6 +201,8 @@ type authErrors_InvalidVerificationTokenError = InvalidVerificationTokenError;
189
201
  declare const authErrors_InvalidVerificationTokenError: typeof InvalidVerificationTokenError;
190
202
  type authErrors_KeyExpiredError = KeyExpiredError;
191
203
  declare const authErrors_KeyExpiredError: typeof KeyExpiredError;
204
+ type authErrors_ReservedUsernameError = ReservedUsernameError;
205
+ declare const authErrors_ReservedUsernameError: typeof ReservedUsernameError;
192
206
  type authErrors_TokenExpiredError = TokenExpiredError;
193
207
  declare const authErrors_TokenExpiredError: typeof TokenExpiredError;
194
208
  type authErrors_UsernameAlreadyTakenError = UsernameAlreadyTakenError;
@@ -198,7 +212,7 @@ declare const authErrors_VerificationTokenPurposeMismatchError: typeof Verificat
198
212
  type authErrors_VerificationTokenTargetMismatchError = VerificationTokenTargetMismatchError;
199
213
  declare const authErrors_VerificationTokenTargetMismatchError: typeof VerificationTokenTargetMismatchError;
200
214
  declare namespace authErrors {
201
- export { authErrors_AccountAlreadyExistsError as AccountAlreadyExistsError, authErrors_AccountDisabledError as AccountDisabledError, authErrors_InsufficientPermissionsError as InsufficientPermissionsError, authErrors_InsufficientRoleError as InsufficientRoleError, authErrors_InvalidCredentialsError as InvalidCredentialsError, authErrors_InvalidKeyFingerprintError as InvalidKeyFingerprintError, authErrors_InvalidTokenError as InvalidTokenError, authErrors_InvalidVerificationCodeError as InvalidVerificationCodeError, authErrors_InvalidVerificationTokenError as InvalidVerificationTokenError, authErrors_KeyExpiredError as KeyExpiredError, authErrors_TokenExpiredError as TokenExpiredError, authErrors_UsernameAlreadyTakenError as UsernameAlreadyTakenError, authErrors_VerificationTokenPurposeMismatchError as VerificationTokenPurposeMismatchError, authErrors_VerificationTokenTargetMismatchError as VerificationTokenTargetMismatchError };
215
+ export { authErrors_AccountAlreadyExistsError as AccountAlreadyExistsError, authErrors_AccountDisabledError as AccountDisabledError, authErrors_InsufficientPermissionsError as InsufficientPermissionsError, authErrors_InsufficientRoleError as InsufficientRoleError, authErrors_InvalidCredentialsError as InvalidCredentialsError, authErrors_InvalidKeyFingerprintError as InvalidKeyFingerprintError, authErrors_InvalidTokenError as InvalidTokenError, authErrors_InvalidVerificationCodeError as InvalidVerificationCodeError, authErrors_InvalidVerificationTokenError as InvalidVerificationTokenError, authErrors_KeyExpiredError as KeyExpiredError, authErrors_ReservedUsernameError as ReservedUsernameError, authErrors_TokenExpiredError as TokenExpiredError, authErrors_UsernameAlreadyTakenError as UsernameAlreadyTakenError, authErrors_VerificationTokenPurposeMismatchError as VerificationTokenPurposeMismatchError, authErrors_VerificationTokenTargetMismatchError as VerificationTokenTargetMismatchError };
202
216
  }
203
217
 
204
218
  /**
@@ -207,4 +221,4 @@ declare namespace authErrors {
207
221
 
208
222
  declare const authErrorRegistry: ErrorRegistry;
209
223
 
210
- export { AccountAlreadyExistsError, AccountDisabledError, authErrors as AuthError, InsufficientPermissionsError, InsufficientRoleError, InvalidCredentialsError, InvalidKeyFingerprintError, InvalidTokenError, InvalidVerificationCodeError, InvalidVerificationTokenError, KeyExpiredError, TokenExpiredError, UsernameAlreadyTakenError, VerificationTokenPurposeMismatchError, VerificationTokenTargetMismatchError, authErrorRegistry };
224
+ export { AccountAlreadyExistsError, AccountDisabledError, authErrors as AuthError, InsufficientPermissionsError, InsufficientRoleError, InvalidCredentialsError, InvalidKeyFingerprintError, InvalidTokenError, InvalidVerificationCodeError, InvalidVerificationTokenError, KeyExpiredError, ReservedUsernameError, TokenExpiredError, UsernameAlreadyTakenError, VerificationTokenPurposeMismatchError, VerificationTokenTargetMismatchError, authErrorRegistry };
package/dist/errors.js CHANGED
@@ -20,6 +20,7 @@ __export(auth_errors_exports, {
20
20
  InvalidVerificationCodeError: () => InvalidVerificationCodeError,
21
21
  InvalidVerificationTokenError: () => InvalidVerificationTokenError,
22
22
  KeyExpiredError: () => KeyExpiredError,
23
+ ReservedUsernameError: () => ReservedUsernameError,
23
24
  TokenExpiredError: () => TokenExpiredError,
24
25
  UsernameAlreadyTakenError: () => UsernameAlreadyTakenError,
25
26
  VerificationTokenPurposeMismatchError: () => VerificationTokenPurposeMismatchError,
@@ -116,6 +117,15 @@ var VerificationTokenTargetMismatchError = class extends ValidationError {
116
117
  this.name = "VerificationTokenTargetMismatchError";
117
118
  }
118
119
  };
120
+ var ReservedUsernameError = class extends ValidationError {
121
+ constructor(data = {}) {
122
+ super({
123
+ message: data.message || "This username is reserved",
124
+ details: { username: data.username, ...data.details }
125
+ });
126
+ this.name = "ReservedUsernameError";
127
+ }
128
+ };
119
129
  var UsernameAlreadyTakenError = class extends ConflictError {
120
130
  constructor(data = {}) {
121
131
  super({
@@ -155,6 +165,7 @@ authErrorRegistry.append([
155
165
  KeyExpiredError,
156
166
  AccountDisabledError,
157
167
  AccountAlreadyExistsError,
168
+ ReservedUsernameError,
158
169
  UsernameAlreadyTakenError,
159
170
  InvalidVerificationCodeError,
160
171
  InvalidVerificationTokenError,
@@ -176,6 +187,7 @@ export {
176
187
  InvalidVerificationCodeError,
177
188
  InvalidVerificationTokenError,
178
189
  KeyExpiredError,
190
+ ReservedUsernameError,
179
191
  TokenExpiredError,
180
192
  UsernameAlreadyTakenError,
181
193
  VerificationTokenPurposeMismatchError,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors/index.ts","../src/errors/auth-errors.ts"],"sourcesContent":["/**\n * Auth Error Exports\n */\n\nimport { ErrorRegistry } from \"@spfn/core/errors\";\n\nimport {\n InvalidCredentialsError,\n InvalidTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountAlreadyExistsError,\n UsernameAlreadyTakenError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n} from './auth-errors';\n\nexport {\n InvalidCredentialsError,\n InvalidTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountAlreadyExistsError,\n UsernameAlreadyTakenError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n} from './auth-errors';\n\nexport const authErrorRegistry = new ErrorRegistry();\nauthErrorRegistry.append([\n InvalidCredentialsError,\n InvalidTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountAlreadyExistsError,\n UsernameAlreadyTakenError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n]);\n\nexport * as AuthError from './auth-errors';","/**\n * Authentication & Authorization Error Classes\n *\n * Custom error classes for auth-specific scenarios\n */\n\nimport {\n ValidationError,\n UnauthorizedError,\n ForbiddenError,\n ConflictError\n} from '@spfn/core/errors';\n\n/**\n * Invalid Credentials Error (401)\n *\n * Thrown when login credentials are incorrect\n */\nexport class InvalidCredentialsError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid credentials', details: data.details });\n this.name = 'InvalidCredentialsError';\n }\n}\n\n/**\n * Invalid Token Error (401)\n *\n * Thrown when authentication token is invalid or malformed\n */\nexport class InvalidTokenError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid authentication token', details: data.details });\n this.name = 'InvalidTokenError';\n }\n}\n\n/**\n * Token Expired Error (401)\n *\n * Thrown when authentication token has expired\n */\nexport class TokenExpiredError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Authentication token has expired', details: data.details });\n this.name = 'TokenExpiredError';\n }\n}\n\n/**\n * Key Expired Error (401)\n *\n * Thrown when public key has expired\n */\nexport class KeyExpiredError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Public key has expired', details: data.details });\n this.name = 'KeyExpiredError';\n }\n}\n\n/**\n * Account Disabled Error (403)\n *\n * Thrown when user account is disabled or inactive\n */\nexport class AccountDisabledError extends ForbiddenError\n{\n constructor(data: { status?: string; message?: string; details?: Record<string, any> } = {})\n {\n const status = data.status || 'disabled';\n super({\n message: data.message || `Account is ${status}`,\n details: { status, ...data.details }\n });\n this.name = 'AccountDisabledError';\n }\n}\n\n/**\n * Account Already Exists Error (409)\n *\n * Thrown when trying to register with existing email/phone\n */\nexport class AccountAlreadyExistsError extends ConflictError\n{\n constructor(data: { identifier?: string; identifierType?: 'email' | 'phone'; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Account already exists',\n details: {\n identifier: data.identifier,\n identifierType: data.identifierType,\n ...data.details\n }\n });\n this.name = 'AccountAlreadyExistsError';\n }\n}\n\n/**\n * Invalid Verification Code Error (400)\n *\n * Thrown when verification code is invalid, expired, or already used\n */\nexport class InvalidVerificationCodeError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid verification code', details: data.details });\n this.name = 'InvalidVerificationCodeError';\n }\n}\n\n/**\n * Invalid Verification Token Error (400)\n *\n * Thrown when verification token is invalid or expired\n */\nexport class InvalidVerificationTokenError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid or expired verification token', details: data.details });\n this.name = 'InvalidVerificationTokenError';\n }\n}\n\n/**\n * Invalid Key Fingerprint Error (400)\n *\n * Thrown when public key fingerprint doesn't match the public key\n */\nexport class InvalidKeyFingerprintError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid key fingerprint', details: data.details });\n this.name = 'InvalidKeyFingerprintError';\n }\n}\n\n/**\n * Verification Token Purpose Mismatch Error (400)\n *\n * Thrown when verification token purpose doesn't match expected purpose\n */\nexport class VerificationTokenPurposeMismatchError extends ValidationError\n{\n constructor(data: { expected?: string; actual?: string; message?: string; details?: Record<string, any> } = {})\n {\n const expected = data.expected || 'unknown';\n const actual = data.actual || 'unknown';\n super({\n message: data.message || `Verification token is for ${actual}, but ${expected} was expected`,\n details: { expected, actual, ...data.details }\n });\n this.name = 'VerificationTokenPurposeMismatchError';\n }\n}\n\n/**\n * Verification Token Target Mismatch Error (400)\n *\n * Thrown when verification token target doesn't match provided email/phone\n */\nexport class VerificationTokenTargetMismatchError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Verification token does not match provided email/phone',\n details: data.details\n });\n this.name = 'VerificationTokenTargetMismatchError';\n }\n}\n\n/**\n * Username Already Taken Error (409)\n *\n * Thrown when trying to set a username that is already in use\n */\nexport class UsernameAlreadyTakenError extends ConflictError\n{\n constructor(data: { username?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Username is already taken',\n details: { username: data.username, ...data.details }\n });\n this.name = 'UsernameAlreadyTakenError';\n }\n}\n\n/**\n * Insufficient Permissions Error (403)\n *\n * Thrown when user lacks required permissions for the operation\n */\nexport class InsufficientPermissionsError extends ForbiddenError\n{\n constructor(data: { requiredPermissions?: string[]; message?: string; details?: Record<string, any> } = {})\n {\n const requiredPermissions = data.requiredPermissions || [];\n super({\n message: data.message || `Missing required permissions: ${requiredPermissions.join(', ')}`,\n details: { requiredPermissions, ...data.details }\n });\n this.name = 'InsufficientPermissionsError';\n }\n}\n\n/**\n * Insufficient Role Error (403)\n *\n * Thrown when user lacks required role for the operation\n */\nexport class InsufficientRoleError extends ForbiddenError\n{\n constructor(data: { requiredRoles?: string[]; message?: string; details?: Record<string, any> } = {})\n {\n const requiredRoles = data.requiredRoles || [];\n super({\n message: data.message || `Required roles: ${requiredRoles.join(', ')}`,\n details: { requiredRoles, ...data.details }\n });\n this.name = 'InsufficientRoleError';\n }\n}"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/errors/index.ts","../src/errors/auth-errors.ts"],"sourcesContent":["/**\n * Auth Error Exports\n */\n\nimport { ErrorRegistry } from \"@spfn/core/errors\";\n\nimport {\n InvalidCredentialsError,\n InvalidTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountAlreadyExistsError,\n ReservedUsernameError,\n UsernameAlreadyTakenError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n} from './auth-errors';\n\nexport {\n InvalidCredentialsError,\n InvalidTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountAlreadyExistsError,\n ReservedUsernameError,\n UsernameAlreadyTakenError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n} from './auth-errors';\n\nexport const authErrorRegistry = new ErrorRegistry();\nauthErrorRegistry.append([\n InvalidCredentialsError,\n InvalidTokenError,\n TokenExpiredError,\n KeyExpiredError,\n AccountDisabledError,\n AccountAlreadyExistsError,\n ReservedUsernameError,\n UsernameAlreadyTakenError,\n InvalidVerificationCodeError,\n InvalidVerificationTokenError,\n InvalidKeyFingerprintError,\n VerificationTokenPurposeMismatchError,\n VerificationTokenTargetMismatchError,\n InsufficientPermissionsError,\n InsufficientRoleError,\n]);\n\nexport * as AuthError from './auth-errors';","/**\n * Authentication & Authorization Error Classes\n *\n * Custom error classes for auth-specific scenarios\n */\n\nimport {\n ValidationError,\n UnauthorizedError,\n ForbiddenError,\n ConflictError\n} from '@spfn/core/errors';\n\n/**\n * Invalid Credentials Error (401)\n *\n * Thrown when login credentials are incorrect\n */\nexport class InvalidCredentialsError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid credentials', details: data.details });\n this.name = 'InvalidCredentialsError';\n }\n}\n\n/**\n * Invalid Token Error (401)\n *\n * Thrown when authentication token is invalid or malformed\n */\nexport class InvalidTokenError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid authentication token', details: data.details });\n this.name = 'InvalidTokenError';\n }\n}\n\n/**\n * Token Expired Error (401)\n *\n * Thrown when authentication token has expired\n */\nexport class TokenExpiredError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Authentication token has expired', details: data.details });\n this.name = 'TokenExpiredError';\n }\n}\n\n/**\n * Key Expired Error (401)\n *\n * Thrown when public key has expired\n */\nexport class KeyExpiredError extends UnauthorizedError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Public key has expired', details: data.details });\n this.name = 'KeyExpiredError';\n }\n}\n\n/**\n * Account Disabled Error (403)\n *\n * Thrown when user account is disabled or inactive\n */\nexport class AccountDisabledError extends ForbiddenError\n{\n constructor(data: { status?: string; message?: string; details?: Record<string, any> } = {})\n {\n const status = data.status || 'disabled';\n super({\n message: data.message || `Account is ${status}`,\n details: { status, ...data.details }\n });\n this.name = 'AccountDisabledError';\n }\n}\n\n/**\n * Account Already Exists Error (409)\n *\n * Thrown when trying to register with existing email/phone\n */\nexport class AccountAlreadyExistsError extends ConflictError\n{\n constructor(data: { identifier?: string; identifierType?: 'email' | 'phone'; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Account already exists',\n details: {\n identifier: data.identifier,\n identifierType: data.identifierType,\n ...data.details\n }\n });\n this.name = 'AccountAlreadyExistsError';\n }\n}\n\n/**\n * Invalid Verification Code Error (400)\n *\n * Thrown when verification code is invalid, expired, or already used\n */\nexport class InvalidVerificationCodeError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid verification code', details: data.details });\n this.name = 'InvalidVerificationCodeError';\n }\n}\n\n/**\n * Invalid Verification Token Error (400)\n *\n * Thrown when verification token is invalid or expired\n */\nexport class InvalidVerificationTokenError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid or expired verification token', details: data.details });\n this.name = 'InvalidVerificationTokenError';\n }\n}\n\n/**\n * Invalid Key Fingerprint Error (400)\n *\n * Thrown when public key fingerprint doesn't match the public key\n */\nexport class InvalidKeyFingerprintError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({ message: data.message || 'Invalid key fingerprint', details: data.details });\n this.name = 'InvalidKeyFingerprintError';\n }\n}\n\n/**\n * Verification Token Purpose Mismatch Error (400)\n *\n * Thrown when verification token purpose doesn't match expected purpose\n */\nexport class VerificationTokenPurposeMismatchError extends ValidationError\n{\n constructor(data: { expected?: string; actual?: string; message?: string; details?: Record<string, any> } = {})\n {\n const expected = data.expected || 'unknown';\n const actual = data.actual || 'unknown';\n super({\n message: data.message || `Verification token is for ${actual}, but ${expected} was expected`,\n details: { expected, actual, ...data.details }\n });\n this.name = 'VerificationTokenPurposeMismatchError';\n }\n}\n\n/**\n * Verification Token Target Mismatch Error (400)\n *\n * Thrown when verification token target doesn't match provided email/phone\n */\nexport class VerificationTokenTargetMismatchError extends ValidationError\n{\n constructor(data: { message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Verification token does not match provided email/phone',\n details: data.details\n });\n this.name = 'VerificationTokenTargetMismatchError';\n }\n}\n\n/**\n * Reserved Username Error (400)\n *\n * Thrown when trying to use a reserved/prohibited username\n */\nexport class ReservedUsernameError extends ValidationError\n{\n constructor(data: { username?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'This username is reserved',\n details: { username: data.username, ...data.details }\n });\n this.name = 'ReservedUsernameError';\n }\n}\n\n/**\n * Username Already Taken Error (409)\n *\n * Thrown when trying to set a username that is already in use\n */\nexport class UsernameAlreadyTakenError extends ConflictError\n{\n constructor(data: { username?: string; message?: string; details?: Record<string, any> } = {})\n {\n super({\n message: data.message || 'Username is already taken',\n details: { username: data.username, ...data.details }\n });\n this.name = 'UsernameAlreadyTakenError';\n }\n}\n\n/**\n * Insufficient Permissions Error (403)\n *\n * Thrown when user lacks required permissions for the operation\n */\nexport class InsufficientPermissionsError extends ForbiddenError\n{\n constructor(data: { requiredPermissions?: string[]; message?: string; details?: Record<string, any> } = {})\n {\n const requiredPermissions = data.requiredPermissions || [];\n super({\n message: data.message || `Missing required permissions: ${requiredPermissions.join(', ')}`,\n details: { requiredPermissions, ...data.details }\n });\n this.name = 'InsufficientPermissionsError';\n }\n}\n\n/**\n * Insufficient Role Error (403)\n *\n * Thrown when user lacks required role for the operation\n */\nexport class InsufficientRoleError extends ForbiddenError\n{\n constructor(data: { requiredRoles?: string[]; message?: string; details?: Record<string, any> } = {})\n {\n const requiredRoles = data.requiredRoles || [];\n super({\n message: data.message || `Required roles: ${requiredRoles.join(', ')}`,\n details: { requiredRoles, ...data.details }\n });\n this.name = 'InsufficientRoleError';\n }\n}"],"mappings":"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","names":[]}
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as _spfn_core_nextjs from '@spfn/core/nextjs';
2
- import { R as RoleConfig, P as PermissionConfig, C as CheckAccountExistsResult, S as SendVerificationCodeResult, a as RegisterResult, L as LoginResult, b as RotateKeyResult, O as OAuthStartResult, U as UserProfile, c as ProfileInfo, m as mainAuthRouter } from './authenticate-Brx2N-Ip.js';
3
- export { k as AuthInitOptions, A as AuthSession, I as INVITATION_STATUSES, n as InvitationStatus, K as KEY_ALGORITHM, l as KeyAlgorithmType, i as PERMISSION_CATEGORIES, j as PermissionCategory, e as SOCIAL_PROVIDERS, p as SocialProvider, d as USER_STATUSES, o as UserStatus, h as VERIFICATION_PURPOSES, g as VERIFICATION_TARGET_TYPES, f as VerificationPurpose, V as VerificationTargetType } from './authenticate-Brx2N-Ip.js';
2
+ import { R as RoleConfig, P as PermissionConfig, C as CheckAccountExistsResult, S as SendVerificationCodeResult, a as RegisterResult, L as LoginResult, b as RotateKeyResult, O as OAuthStartResult, U as UserProfile, c as ProfileInfo, m as mainAuthRouter } from './authenticate-CGslXjZb.js';
3
+ export { k as AuthInitOptions, A as AuthSession, I as INVITATION_STATUSES, n as InvitationStatus, K as KEY_ALGORITHM, l as KeyAlgorithmType, i as PERMISSION_CATEGORIES, j as PermissionCategory, e as SOCIAL_PROVIDERS, p as SocialProvider, d as USER_STATUSES, o as UserStatus, h as VERIFICATION_PURPOSES, g as VERIFICATION_TARGET_TYPES, f as VerificationPurpose, V as VerificationTargetType } from './authenticate-CGslXjZb.js';
4
4
  import * as _spfn_core_route from '@spfn/core/route';
5
5
  import { HttpMethod } from '@spfn/core/route';
6
6
  import * as _sinclair_typebox from '@sinclair/typebox';
@@ -168,7 +168,7 @@ declare const authApi: _spfn_core_nextjs.Client<_spfn_core_route.Router<{
168
168
  id: number;
169
169
  name: string;
170
170
  displayName: string;
171
- category: "auth" | "custom" | "user" | "rbac" | "system" | undefined;
171
+ category: "custom" | "user" | "auth" | "rbac" | "system" | undefined;
172
172
  }[];
173
173
  userId: number;
174
174
  email: string | null;
package/dist/index.js CHANGED
@@ -102,6 +102,15 @@ var VerificationTokenTargetMismatchError = class extends ValidationError {
102
102
  this.name = "VerificationTokenTargetMismatchError";
103
103
  }
104
104
  };
105
+ var ReservedUsernameError = class extends ValidationError {
106
+ constructor(data = {}) {
107
+ super({
108
+ message: data.message || "This username is reserved",
109
+ details: { username: data.username, ...data.details }
110
+ });
111
+ this.name = "ReservedUsernameError";
112
+ }
113
+ };
105
114
  var UsernameAlreadyTakenError = class extends ConflictError {
106
115
  constructor(data = {}) {
107
116
  super({
@@ -141,6 +150,7 @@ authErrorRegistry.append([
141
150
  KeyExpiredError,
142
151
  AccountDisabledError,
143
152
  AccountAlreadyExistsError,
153
+ ReservedUsernameError,
144
154
  UsernameAlreadyTakenError,
145
155
  InvalidVerificationCodeError,
146
156
  InvalidVerificationTokenError,