Open Serdans opened 10 months ago
Could you paste the debug logs here (redacting any relevant values) please?
Actually I don't think the include matters. I'm also getting it for regular selects.
prisma-field-encryption:setup Keys: {
prisma-field-encryption:setup encryptionKey: {
prisma-field-encryption:setup raw: Uint8Array(32) [
xX
prisma-field-encryption:setup ],
prisma-field-encryption:setup fingerprint: '83fa61c5'
prisma-field-encryption:setup },
prisma-field-encryption:setup keychain: { '83fa61c5': { key: [Object], createdAt: 1699968990545 } }
prisma-field-encryption:setup } +0ms
prisma-field-encryption:setup Models: {
prisma-field-encryption:setup User: {
prisma-field-encryption:setup cursor: 'id',
prisma-field-encryption:setup fields: { email: [Object] },
prisma-field-encryption:setup connections: { subscriptions: [Object], createdSubscriptions: [Object] }
prisma-field-encryption:setup },
prisma-field-encryption:setup Subscription: {
prisma-field-encryption:setup cursor: 'id',
prisma-field-encryption:setup fields: {},
prisma-field-encryption:setup connections: { customer: [Object], admin: [Object] }
prisma-field-encryption:setup }
prisma-field-encryption:setup } +20ms
✓ Compiled in 333ms (332 modules)
prisma:query db.User.aggregate([ { $match: { $expr: { $and: [ { $eq: [ "$accountId", { $literal: "30712252-966d-4b17-a2ca-650f0011c106", }, ], }, { $ne: [ "$accountId", "$$REMOVE", ], }, ], }, }, }, { $limit: 1, }, { $project: { _id: 1, accountId: 1, email: 1, role: 1, }, }, ])
prisma:query db.User.aggregate([ { $match: { $expr: { $and: [ { $eq: [ "$accountId", { $literal: "30712252-966d-4b17-a2ca-650f0011c106", }, ], }, { $ne: [ "$accountId", "$$REMOVE", ], }, ], }, }, }, { $limit: 1, }, { $project: { _id: 1, accountId: 1, email: 1, role: 1, }, }, ])
AUTH USER {
id: 'clojv3dbz0000o60gfmquqw6u',
accountId: '30712252-966d-4b17-a2ca-650f0011c106',
email: 'v1.aesgcm256.83fa61c5.b_AMLTv_7VbNSS9n.cFmJw2yujwmdYTEa3yePa5Hdby2wD0BVp97b6q_IBY9VOvI=',
role: 'ADMIN'
}
○ Compiling /favicon.ico/route ...
✓ Compiled /api/user/[userId]/subscription/route in 1523ms (864 modules)
prisma:warn In production, we recommend using `prisma generate --no-engine` (See: `prisma generate --help`)
2023-11-14T13:36:33.669Z prisma-field-encryption:setup Keys: {
encryptionKey: {
raw: Uint8Array(32) [
214, 112, 94, 194, 189, 90, 64, 162,
98, 147, 152, 213, 33, 131, 83, 253,
245, 19, 20, 191, 36, 3, 152, 3,
38, 190, 186, 61, 241, 154, 57, 201
],
fingerprint: '83fa61c5'
},
keychain: { '83fa61c5': { key: [Object], createdAt: 1699968993665 } }
}
2023-11-14T13:36:33.699Z prisma-field-encryption:setup Models: {
User: {
cursor: 'id',
fields: { email: [Object] },
connections: { subscriptions: [Object], createdSubscriptions: [Object] }
},
Subscription: {
cursor: 'id',
fields: {},
connections: { customer: [Object], admin: [Object] }
}
}
prisma:query db.Subscription.aggregate([ { $match: { $expr: { $and: [ { $eq: [ "$customerId", { $literal: "clojv3dbz0000o60gfmquqw6u", }, ], }, { $ne: [ "$customerId", "$$REMOVE", ], }, ], }, }, }, { $sort: { expiresOn: -1, }, }, { $project: { _id: 1, name: 1, paymentUrl: 1, expiresOn: 1, customerId: 1, adminId: 1, }, }, ])
Ah I see, you have to do special things with Next.js to prevent hot-reloading to stack up the middlewares, see https://github.com/47ng/prisma-field-encryption/issues/61#issuecomment-1585658196.
Let me know if that fixes it for you.
I instantiate my prisma client like so, which is roughly the same as in that comment I think and it doesn't work:
import { PrismaClient } from "@prisma/client/edge";
import { withAccelerate } from "@prisma/extension-accelerate";
import { fieldEncryptionExtension } from 'prisma-field-encryption'
const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
export const prisma =
globalForPrisma.prisma ||
new PrismaClient({
log:
process.env.NODE_ENV === "development"
? ["query", "error", "warn"]
: ["error"],
})
.$extends(withAccelerate())
.$extends(fieldEncryptionExtension());
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
export default prisma;
I also have the same problem, with a similar setup (I tried accelerate too, but removed it for now).
When I am on prisma ~4.3
and prisma-field-encryption@~1.4.5
the cypher gets decoded correctly. I tried prisma ~5.1
and then ~5.5
on prisma-field-encryption@^1.5.0
and the cypher does not get decoded. I use the same encryption keys.
Here is my debug output:
And my globally configured prisma on NextJs 14:
On my case I am not doing this within an include although might be why I did a root resolver in this sample code
/*
* This is a workaround, as I am not sure how type-graphql-prisma handles queries. Nested resolvers that
* need the pin found themselves with an encrypted value instead of an unencrypted one. This works around that,
* although not performant.
*/
@FieldResolver(() => String)
async pin(@Root() user: User, @Ctx() { prisma }: Context): Promise<string> {
const foundUser = await prisma.user.findUnique({ where: { id: user.id } });
return foundUser?.pin || user.pin;
}
I also double checked that the encrypted pin is not double encrypted, it is the same as found within the database
Another interesting thing here is that I tried using the deprecated $use
and it works
// prisma.$extends(fieldEncryptionExtension({ dmmf: Prisma.dmmf }));
prisma.$use(fieldEncryptionMiddleware({ dmmf: Prisma.dmmf }))
I noticed that the difference between the extension and the middleware is that the extension uses Prisma.defineExtension
. Since my setup uses a custom output directory, I tried removing that from the compiled extension.js
file in favor of just returning an object like documented here, but that did not work either.
Maybe that is a separate issue though, not too sure.
When doing a query which includes encrypted fields, rather than selecting them directly, the field will return encrypted. Example of my prisma schema: