Skip to content
This repository was archived by the owner on Apr 19, 2023. It is now read-only.

Commit 3e259b4

Browse files
♻️ Use access toke ngenerator abstraction
1 parent 527ab9a commit 3e259b4

2 files changed

Lines changed: 49 additions & 15 deletions

File tree

src/modules/auth/auth.service.ts

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,8 @@ export class AuthService {
5555
await this.prisma.sessions.create({
5656
data: { token, ipAddress, userAgent, user: { connect: { id } } },
5757
});
58-
const payload: AccessTokenClaims = {
59-
sub: `user${id}`,
60-
scopes: ['example-scope'],
61-
};
6258
return {
63-
accessToken: this.jwtService.sign(payload, {
64-
expiresIn: this.configService.get<string>('security.accessTokenExpiry'),
65-
}),
59+
accessToken: await this.getAccessToken(id),
6660
refreshToken: token,
6761
};
6862
}
@@ -133,15 +127,37 @@ export class AuthService {
133127
data: { ipAddress, userAgent },
134128
});
135129
return {
136-
accessToken: this.jwtService.sign(
137-
{ sub: `user${session.user.id}` },
138-
{
139-
expiresIn: this.configService.get<string>(
140-
'security.accessTokenExpiry',
141-
),
142-
},
143-
),
130+
accessToken: await this.getAccessToken(session.user.id),
144131
refreshToken: token,
145132
};
146133
}
134+
135+
private async getAccessToken(userId: number): Promise<string> {
136+
const scopes = await this.getScopes(userId);
137+
const payload: AccessTokenClaims = {
138+
sub: `user${userId}`,
139+
scopes,
140+
};
141+
return this.jwtService.sign(payload, {
142+
expiresIn: this.configService.get<string>('security.accessTokenExpiry'),
143+
});
144+
}
145+
146+
async getScopes(userId: number): Promise<string[]> {
147+
const scopes: string[] = [`user${userId}:*`];
148+
const memberships = await this.prisma.memberships.findMany({
149+
where: { user: { id: userId } },
150+
select: { id: true, role: true, group: { select: { id: true } } },
151+
});
152+
memberships.forEach(membership => {
153+
scopes.push(`membership${membership.id}:*`);
154+
if (membership.role === 'OWNER')
155+
scopes.push(`group${membership.group.id}:*`);
156+
if (membership.role === 'ADMIN')
157+
scopes.push(`group${membership.group.id}:write-*`);
158+
if (membership.role !== 'OWNER')
159+
scopes.push(`group${membership.group.id}:read-*`);
160+
});
161+
return scopes;
162+
}
147163
}

src/modules/auth/scope.guard.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
2+
import { Reflector } from '@nestjs/core';
3+
import { AccessTokenParsed } from './auth.interface';
4+
5+
@Injectable()
6+
export class ScopesGuard implements CanActivate {
7+
constructor(private reflector: Reflector) {}
8+
9+
canActivate(context: ExecutionContext): boolean {
10+
const scopes = this.reflector.get<string[]>('scopes', context.getHandler());
11+
console.log(scopes);
12+
if (!scopes) return true;
13+
const request = context.switchToHttp().getRequest();
14+
const user: AccessTokenParsed = request.user;
15+
16+
// return user.scopes.includes(scopes);
17+
}
18+
}

0 commit comments

Comments
 (0)