init: scaffold complet Sakuin — backend NestJS + frontend SvelteKit + CI/CD + deploy VPS
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 29s
All checks were successful
CI/CD — Build & Deploy / Build & Deploy (push) Successful in 29s
Backend: 5 modules (auth, user, work, list, health), AniList GraphQL proxy, SuperOAuth PKCE introspection, XP system, migrations TypeORM. Frontend: SvelteKit adapter-node, PWA manifest, dark theme, pages home/search/list/profile/callback. Infra: CI/CD Gitea vps-runner, Apache vhost SSL, pm2 sakuin-backend + sakuin-frontend, port 4002. License: BSL 1.1 (Apache 2.0 en 2028).
This commit is contained in:
50
backend/src/auth/auth.guard.ts
Normal file
50
backend/src/auth/auth.guard.ts
Normal file
@@ -0,0 +1,50 @@
|
||||
import {
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
Injectable,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
@Injectable()
|
||||
export class AuthGuard implements CanActivate {
|
||||
constructor(private readonly configService: ConfigService) {}
|
||||
|
||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
const request = context.switchToHttp().getRequest();
|
||||
const token = this.extractToken(request);
|
||||
|
||||
if (!token) {
|
||||
throw new UnauthorizedException('No token provided');
|
||||
}
|
||||
|
||||
const userInfo = await this.introspect(token);
|
||||
if (!userInfo) {
|
||||
throw new UnauthorizedException('Invalid token');
|
||||
}
|
||||
|
||||
request.user = userInfo;
|
||||
return true;
|
||||
}
|
||||
|
||||
private extractToken(request: any): string | null {
|
||||
const authHeader = request.headers.authorization;
|
||||
if (authHeader?.startsWith('Bearer ')) {
|
||||
return authHeader.slice(7);
|
||||
}
|
||||
return request.cookies?.access_token || null;
|
||||
}
|
||||
|
||||
private async introspect(token: string): Promise<any> {
|
||||
const url = this.configService.get('SUPEROAUTH_URL');
|
||||
try {
|
||||
const res = await fetch(`${url}/api/v1/user/profile`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
if (!res.ok) return null;
|
||||
return res.json();
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
8
backend/src/auth/auth.module.ts
Normal file
8
backend/src/auth/auth.module.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { AuthGuard } from './auth.guard';
|
||||
|
||||
@Module({
|
||||
providers: [AuthGuard],
|
||||
exports: [AuthGuard],
|
||||
})
|
||||
export class AuthModule {}
|
||||
Reference in New Issue
Block a user