mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-15 08:41:10 +02:00
79 lines
2.2 KiB
TypeScript
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,
|
|
});
|
|
}
|
|
}
|