门店账户多账号
This commit is contained in:
@@ -13,6 +13,8 @@ export interface AuthUser {
|
||||
clientApp: ClientApp;
|
||||
sub: string;
|
||||
phoneVerified: boolean;
|
||||
/** Selected store after POST /shop/auth/select-store */
|
||||
storeId?: bigint;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
@@ -41,6 +43,9 @@ export class JwtAuthGuard implements CanActivate {
|
||||
clientApp,
|
||||
sub: payload.sub,
|
||||
phoneVerified: !!payload.phoneVerified,
|
||||
...(payload.storeId != null && payload.storeId !== ''
|
||||
? { storeId: BigInt(payload.storeId) }
|
||||
: {}),
|
||||
} satisfies AuthUser;
|
||||
return true;
|
||||
} catch (err) {
|
||||
|
||||
@@ -29,6 +29,9 @@ export class OptionalJwtAuthGuard implements CanActivate {
|
||||
clientApp,
|
||||
sub: payload.sub,
|
||||
phoneVerified: !!payload.phoneVerified,
|
||||
...(payload.storeId != null && payload.storeId !== ''
|
||||
? { storeId: BigInt(payload.storeId) }
|
||||
: {}),
|
||||
} satisfies AuthUser;
|
||||
} catch {
|
||||
/* ignore invalid token */
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { CanActivate, ExecutionContext, ForbiddenException, Injectable } from '@nestjs/common';
|
||||
import type { AuthUser } from './jwt-auth.guard';
|
||||
|
||||
/** Shop business APIs require JWT claim storeId (after select-store). */
|
||||
@Injectable()
|
||||
export class ShopStoreGuard implements CanActivate {
|
||||
canActivate(context: ExecutionContext): boolean {
|
||||
const req = context.switchToHttp().getRequest();
|
||||
const user = req.user as AuthUser | undefined;
|
||||
if (!user?.storeId) {
|
||||
throw new ForbiddenException('请先选择门店');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import { ForbiddenException, Injectable } from '@nestjs/common';
|
||||
import { PrismaService } from '../prisma/prisma.module';
|
||||
import type { AuthUser } from '../guards/jwt-auth.guard';
|
||||
|
||||
@Injectable()
|
||||
export class StoreMembershipService {
|
||||
constructor(private readonly prisma: PrismaService) {}
|
||||
|
||||
async assertStoreMembership(accountId: bigint, storeId: bigint) {
|
||||
const binding = await this.prisma.storeAccountStore.findUnique({
|
||||
where: {
|
||||
storeAccountId_storeId: { storeAccountId: accountId, storeId },
|
||||
},
|
||||
});
|
||||
if (!binding) {
|
||||
throw new ForbiddenException('无权访问该门店');
|
||||
}
|
||||
return binding;
|
||||
}
|
||||
|
||||
requireShopStoreId(user: AuthUser): bigint {
|
||||
if (!user.storeId) {
|
||||
throw new ForbiddenException('请先选择门店');
|
||||
}
|
||||
return user.storeId;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user