managarten/packages/shared-errors/src/errors/auth-error.ts
Wuesteon 9c47119535 Fix wrong type
import, make auth and chat work
2025-12-04 23:25:25 +01:00

79 lines
2.2 KiB
TypeScript

import { ErrorCode } from '../types/error-codes';
import { AppError } from './app-error';
import type { ErrorContext } from './app-error';
type AuthErrorCode =
| ErrorCode.AUTHENTICATION_REQUIRED
| ErrorCode.INVALID_TOKEN
| ErrorCode.TOKEN_EXPIRED
| ErrorCode.PERMISSION_DENIED
| ErrorCode.RESOURCE_NOT_OWNED;
/**
* Error for authentication and authorization failures.
* HTTP Status: 401 (auth) or 403 (authorization)
*
* @example
* ```typescript
* // Authentication errors (401)
* return err(AuthError.unauthorized());
* return err(AuthError.invalidToken('Token has been revoked'));
* return err(AuthError.tokenExpired());
*
* // Authorization errors (403)
* return err(AuthError.forbidden('Admin access required'));
* return err(AuthError.notOwned('Story', storyId));
* ```
*/
export class AuthError extends AppError {
constructor(code: AuthErrorCode, message: string, context?: ErrorContext) {
super({ code, message, context });
this.name = 'AuthError';
}
/**
* Create an error for missing authentication.
* HTTP 401 Unauthorized
*/
static unauthorized(message = 'Authentication required'): AuthError {
return new AuthError(ErrorCode.AUTHENTICATION_REQUIRED, message);
}
/**
* Create an error for an invalid token.
* HTTP 401 Unauthorized
*/
static invalidToken(message = 'Invalid or malformed token'): AuthError {
return new AuthError(ErrorCode.INVALID_TOKEN, message);
}
/**
* Create an error for an expired token.
* HTTP 401 Unauthorized
*/
static tokenExpired(message = 'Token has expired'): AuthError {
return new AuthError(ErrorCode.TOKEN_EXPIRED, message);
}
/**
* Create an error for insufficient permissions.
* HTTP 403 Forbidden
*/
static forbidden(message = 'Permission denied'): AuthError {
return new AuthError(ErrorCode.PERMISSION_DENIED, message);
}
/**
* Create an error when a user tries to access a resource they don't own.
* HTTP 403 Forbidden
*
* @param resourceType - Type of resource (e.g., 'Story', 'Character')
* @param resourceId - ID of the resource
*/
static notOwned(resourceType: string, resourceId: string): AuthError {
return new AuthError(ErrorCode.RESOURCE_NOT_OWNED, `${resourceType} does not belong to you`, {
resourceType,
resourceId,
});
}
}