如何处理PrismaClientValidationError?

问题描述 投票:0回答:1

我正在使用nestjs、prisma、jwt 编写注销和刷新令牌函数。但我遇到了无效的

this.prisma.user.updateMany()
调用。这是详细的错误。

注销功能错误:

Invalid `this.prisma.user.updateMany()` invocation in
...auth.service.ts:45:32
  42 }
  43
  44 async logout(userId: number) {
→ 45     await this.prisma.user.updateMany({
           where: {
             id: {
               sub: 5,
               ~~~
               email: "dummymail",
               iat: 1713191159,
               exp: 1713192059,
         ?     equals?: Int | IntFieldRefInput,
         ?     in?: Int[],
         ?     notIn?: Int[],
         ?     lt?: Int | IntFieldRefInput,
         ?     lte?: Int | IntFieldRefInput,
         ?     gt?: Int | IntFieldRefInput,
         ?     gte?: Int | IntFieldRefInput,
         ?     not?: Int | NestedIntFilter
             },
             hashedRt: {
               not: null
             }
           },
           data: {
             hashedRt: null
           }
         })

Unknown argument `sub`. Did you mean `in`? Available options are marked with ?.
PrismaClientValidationError:

refreshtoken函数错误:

Invalid `this.prisma.user.findUnique()` invocation in
auth.service.ts:60:45

  57 }
  58
  59 async refreshTokens(userId: number, rt: string) {
→ 60     const user = await this.prisma.user.findUnique({
           where: {
             id: {
               sub: 5,
               email: "[email protected]",
               iat: 1713191159,
               exp: 1713795959,
               refreshToken: "token is here"
             }
             ~~~~~~~~~~~~~~~~~~~~~~~
           }
         })

Argument `id`: Invalid value provided. Expected Int, provided Object.
PrismaClientValidationError:

这是 auth.service.ts 源代码:

import { ForbiddenException, Injectable } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
import { AuthDto } from './dto/auth.dto';
import * as bcrypt from 'bcrypt';
import { Tokens } from './types';
import { JwtService } from '@nestjs/jwt';

@Injectable()
export class AuthService {
    constructor(private prisma: PrismaService,
    private jwtService: JwtService){}

    async signupLocal(dto: AuthDto): Promise<Tokens> {
        const hash = await this.hashData(dto.password);

        const newUser = await this.prisma.user.create({
           data:{
                email: dto.email,
                hash,
            },
        });
        const tokens = await this.getTokens(newUser.id, newUser.email);
        await this.updateRtHash(newUser.id, tokens.refresh_token);
        return tokens;
    }

    async signinLocal(dto:AuthDto): Promise<Tokens> {
        const user = await this.prisma.user.findUnique({
            where:{
                email: dto.email,
            },
        });

        if (!user) throw new ForbiddenException("Oruulkue");

        const passwordMatches = await bcrypt.compare(dto.password, user.hash);
        if (!passwordMatches) throw new ForbiddenException("Oruulkue");

        const tokens = await this.getTokens(user.id, user.email);
        await this.updateRtHash(user.id, tokens.refresh_token);
        return tokens;
    }

    async logout(userId: number) {
        await this.prisma.user.updateMany({
            where:{
                id:userId, 
                hashedRt: {
                    not: null,
                }
            },
            data: {
                hashedRt: null,
            }
        });
        return true;
    }
    
    async refreshTokens(userId: number, rt: string) {
        const user = await this.prisma.user.findUnique({//
            where: {
                id: userId,
            },
        });
        if(!user || !user.hashedRt) throw new ForbiddenException("Oruulkue")
        
        const rtMatches = await bcrypt.compare(rt, user.hashedRt)
        if(!rtMatches) throw new ForbiddenException("Oruulkue")

        const tokens = await this.getTokens(user.id, user.email);
        await this.updateRtHash(user.id, tokens.refresh_token);
        return tokens;
    }

    async updateRtHash(userId: number, rt: string){
        const hash = await this.hashData(rt)
        await this.prisma.user.update({
            where: {
                id: userId,
            },
            data: {
                hashedRt: hash,
            },
        });
    }

    hashData(data: string){
        return bcrypt.hash(data, 10);
    }

    async getTokens(userId: number, email: string){
        const [at, rt] = await Promise.all([
            this.jwtService.signAsync(
                {
                    sub: userId,
                    email,
                },
                {
                    secret: 'at-secret',
                    expiresIn: 60*15,
                },
            ),
            this.jwtService.signAsync(
                {
                    sub: userId,
                    email,
                },
                {
                    secret: 'rt-secret',
                    expiresIn: 60*60*24*7,
                },  
            ),
        ]);

        return{
            access_token: at,
            refresh_token: rt,
        };
    }

}

之前有人解决过这个错误吗? 谢谢你。

如果有人之前解决过这个错误,请帮助我处理它。我是 TypeScript 新手。谢谢你。

node.js nestjs prisma
1个回答
0
投票

您的

where
条款不正确。您似乎正在尝试将值添加到过滤器中。

你应该做类似的事情:

async logout(userId: number) {
  await this.prisma.user.updateMany({
    // Your filter: which records to update
    where: {
      id: 5
    },
    // The data
    data: {
      email: "dummymail",
      iat: 1713191159,
      exp: 1713192059,
    },
  });
};

查看 Prisma 的文档,了解

updateMany
(以及就此而言的其他声明)的工作原理。

sub
是否意味着更新id值低于5的记录?如果是,您应该使用
lt
(低于)或
lte
(低于或等于):

// ...
where: {
  id: {
    lt: 5
  },
},
data: { ... }

请参阅有关过滤条件的文档。

© www.soinside.com 2019 - 2024. All rights reserved.