mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-15 00:41:09 +02:00
feat(mana-core-nestjs): add OptionalAuthGuard and Public decorator
- Add OptionalAuthGuard for endpoints that allow unauthenticated access - Add Public decorator to mark routes as public - Export new guards and decorators from package - Add subpath exports for guards and decorators 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
a34a3418d2
commit
c90c79d6b7
6 changed files with 100 additions and 0 deletions
|
|
@ -9,6 +9,16 @@
|
|||
"types": "./dist/index.d.ts",
|
||||
"import": "./dist/index.js",
|
||||
"require": "./dist/index.js"
|
||||
},
|
||||
"./guards": {
|
||||
"types": "./dist/guards/index.d.ts",
|
||||
"import": "./dist/guards/index.js",
|
||||
"require": "./dist/guards/index.js"
|
||||
},
|
||||
"./decorators": {
|
||||
"types": "./dist/decorators/index.d.ts",
|
||||
"import": "./dist/decorators/index.js",
|
||||
"require": "./dist/decorators/index.js"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
export { CurrentUser, JwtPayload } from './current-user.decorator';
|
||||
export { Public, IS_PUBLIC_KEY } from './public.decorator';
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import { SetMetadata } from '@nestjs/common';
|
||||
|
||||
export const IS_PUBLIC_KEY = 'isPublic';
|
||||
|
||||
/**
|
||||
* Decorator to mark a route as public (no authentication required)
|
||||
*/
|
||||
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
export { AuthGuard } from './auth.guard';
|
||||
export { OptionalAuthGuard } from './optional-auth.guard';
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
import {
|
||||
Injectable,
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
Inject,
|
||||
Optional,
|
||||
} from '@nestjs/common';
|
||||
import * as jwt from 'jsonwebtoken';
|
||||
import { MANA_CORE_OPTIONS } from '../mana-core.module';
|
||||
import { ManaCoreModuleOptions } from '../interfaces/mana-core-options.interface';
|
||||
|
||||
/**
|
||||
* Optional auth guard - allows unauthenticated requests but still extracts user info if token is present
|
||||
*/
|
||||
@Injectable()
|
||||
export class OptionalAuthGuard implements CanActivate {
|
||||
constructor(
|
||||
@Optional()
|
||||
@Inject(MANA_CORE_OPTIONS)
|
||||
private readonly options?: ManaCoreModuleOptions
|
||||
) {}
|
||||
|
||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
const request = context.switchToHttp().getRequest();
|
||||
const token = this.extractTokenFromHeader(request);
|
||||
|
||||
if (!token) {
|
||||
// No token - allow request but user will be undefined
|
||||
request.user = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
// Decode the token to extract user information
|
||||
const decoded = jwt.decode(token) as jwt.JwtPayload | null;
|
||||
|
||||
if (decoded && decoded.sub) {
|
||||
// Attach user info to request
|
||||
request.user = {
|
||||
sub: decoded.sub,
|
||||
email: decoded.email || '',
|
||||
role: decoded.role || 'user',
|
||||
app_id: decoded.app_id,
|
||||
iat: decoded.iat,
|
||||
exp: decoded.exp,
|
||||
};
|
||||
|
||||
// Store raw token for downstream services
|
||||
request.accessToken = token;
|
||||
|
||||
if (this.options?.debug) {
|
||||
console.log('[OptionalAuthGuard] User authenticated:', decoded.sub);
|
||||
}
|
||||
} else {
|
||||
request.user = null;
|
||||
}
|
||||
} catch (error) {
|
||||
if (this.options?.debug) {
|
||||
console.error('[OptionalAuthGuard] Token decode failed:', error);
|
||||
}
|
||||
request.user = null;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private extractTokenFromHeader(request: any): string | undefined {
|
||||
const authHeader = request.headers.authorization;
|
||||
if (!authHeader) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const [type, token] = authHeader.split(' ');
|
||||
return type === 'Bearer' ? token : undefined;
|
||||
}
|
||||
}
|
||||
|
|
@ -10,9 +10,11 @@ export {
|
|||
|
||||
// Guards
|
||||
export { AuthGuard } from './guards/auth.guard';
|
||||
export { OptionalAuthGuard } from './guards/optional-auth.guard';
|
||||
|
||||
// Decorators
|
||||
export { CurrentUser, JwtPayload } from './decorators/current-user.decorator';
|
||||
export { Public, IS_PUBLIC_KEY } from './decorators/public.decorator';
|
||||
|
||||
// Services
|
||||
export {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue