HemmeligOrg / Hemmelig.app

Keep your sensitive information out of chat logs, emails, and more with encrypted secrets.
https://hemmelig.app
MIT License
684 stars 59 forks source link

Invalid `prisma.user.create()` invocation with v5.15.4 #246

Closed tryallthethings closed 7 months ago

tryallthethings commented 8 months ago

Description

After the latest update my docker container doesn't start up properly anymore as long as the following environment variables are in my docker-compose.yml. Once removed, it starts and works normally.

      - SECRET_ROOT_USER=root
      - SECRET_ROOT_PASSWORD=iamroot # The admin user password (Change this only after the first sign in! Do NOT change now!!!)
      - SECRET_ROOT_EMAIL=yourown@email

The errors are repeated indefinitely and the web interface does not respond.

Docker log:

2023-12-31T23:07:28.765483396Z 
2023-12-31T23:07:28.765519616Z > hemmelig@5.0.0 start
2023-12-31T23:07:28.765525856Z > prisma migrate deploy && node server.js
2023-12-31T23:07:28.765529466Z 
2023-12-31T23:07:29.351337128Z Environment variables loaded from .env
2023-12-31T23:07:29.351591329Z Prisma schema loaded from prisma/schema.prisma
2023-12-31T23:07:29.354383604Z Datasource "db": SQLite database "hemmelig.db" at "file:../database/hemmelig.db"
2023-12-31T23:07:29.387158028Z 
2023-12-31T23:07:29.387178688Z 13 migrations found in prisma/migrations
2023-12-31T23:07:29.387215698Z 
2023-12-31T23:07:29.388764767Z 
2023-12-31T23:07:29.388848827Z No pending migrations to apply.
2023-12-31T23:07:30.294904047Z 2024/01/01 12:07AM 30 | pid=19 hostname=hemmelig msg=Server listening at http://0.0.0.0:3000 
2023-12-31T23:07:30.562508191Z /home/node/hemmelig/node_modules/@prisma/client/runtime/library.js:174
2023-12-31T23:07:30.562544791Z `)}a(cs,"checkAlter");function Dh(e){return Array.isArray(e)}a(Dh,"isReadonlyArray");var ps=a((e,t)=>([r,...n])=>{let i="",o;if(typeof r=="string")i=r,o={values:sr(n||[]),__prismaRawParameters__:!0},t.includes("executeRaw")&&cs(i,n,"prisma.$executeRawUnsafe(<SQL>, [...values])");else if(Dh(r))switch(e._activeProvider){case"sqlite":case"mysql":{let s=new he(r,n);i=s.sql,o={values:sr(s.values),__prismaRawParameters__:!0};break}case"cockroachdb":case"postgresql":{let s=new he(r,n);i=s.text,t.includes("executeRaw")&&cs(i,s.values,"prisma.$executeRaw`<SQL>`"),o={values:sr(s.values),__prismaRawParameters__:!0};break}case"sqlserver":{i=us(r),o={values:sr(n),__prismaRawParameters__:!0};break}default:throw new Error(`The ${e._activeProvider} provider does not support ${t}`)}else{switch(e._activeProvider){case"sqlite":case"mysql":i=r.sql;break;case"cockroachdb":case"postgresql":i=r.text,t.includes("executeRaw")&&cs(i,r.values,"prisma.$executeRaw(sql`<SQL>`)");break;case"sqlserver":i=us(r.strings);break;default:throw new Error(`The ${e._activeProvider} provider does not support ${t}`)}o={values:sr(r.values),__prismaRawParameters__:!0}}return o?.values?Mc(`prisma.${t}(${i}, ${o.values})`):Mc(`prisma.${t}(${i})`),{query:i,parameters:o}},"rawQueryArgsMapper");function Nc(e,t=()=>{}){let r,n=new Promise(i=>r=i);return{then(i){return--e===0&&r(t()),i?.(n)}}}a(Nc,"getLockCountPromise");function Rc(e){return typeof e=="string"?e:e.reduce((t,r)=>{let n=typeof r=="string"?r:r.level;return n==="query"?t:t&&(r==="info"||t==="info")?"info":n},void 0)}a(Rc,"getLogLevel");function Ic(e,t,r){let n=Fc(e,r),i=Fc(t,r),o=Object.values(i).map(l=>l[l.length-1]),s=Object.keys(i);return Object.entries(n).forEach(([l,u])=>{s.includes(l)||o.push(u[u.length-1])}),o}a(Ic,"mergeBy");var Fc=a((e,t)=>e.reduce((r,n)=>{let i=t(n);return r[i]||(r[i]=[]),r[i].push(n),r},{}),"groupBy");var cn=class{constructor(){this._middlewares=[]}use(t){this._middlewares.push(t)}get(t){return this._middlewares[t]}has(t){return!!this._middlewares[t]}length(){return this._middlewares.length}};a(cn,"MiddlewareHandler");var $c=O(Rr());function Dc({result:e,modelName:t,select:r,extensions:n}){let i=n.getAllComputedFields(t);if(!i)return e;let o=[],s=[];for(let l of Object.values(i)){if(r){if(!r[l.name])continue;let u=l.needs.filter(c=>!r[c]);u.length>0&&s.push(es(u))}kh(e,l.needs)&&o.push($h(l,ft(e,o)))}return o.length>0||s.length>0?ft(e,[...o,...s]):e}a(Dc,"applyResultExtensions");function kh(e,t){return t.every(r=>jo(e,r))}a(kh,"areNeedsMet");function $h(e,t){return vt(pt(e.name,()=>e.compute(t)))}a($h,"computedPropertyLayer");function Fi({visitor:e,result:t,args:r,dmmf:n,model:i}){if(Array.isArray(t)){for(let s=0;s<t.length;s++)t[s]=Fi({result:t[s],args:r,model:i,dmmf:n,visitor:e});return t}let o=e(t,i,r)??t;return r.include&&kc({includeOrSelect:r.include,result:o,parentModel:i,dmmf:n,visitor:e}),r.select&&kc({includeOrSelect:r.select,result:o,parentModel:i,dmmf:n,visitor:e}),o}a(Fi,"visitQueryResult");function kc({includeOrSelect:e,result:t,parentModel:r,dmmf:n,visitor:i}){for(let[o,s]of Object.entries(e)){if(!s||t[o]==null)continue;let l=r.fields.find(c=>c.name===o);if(!l||l.kind!=="object"||!l.relationName)continue;let u=typeof s=="object"?s:{};t[o]=Fi({visitor:i,result:t[o],args:u,model:n.getModelMap()[l.type],dmmf:n})}}a(kc,"visitNested");var pn=class{constructor(t){this.options=t;this.tickActive=!1;this.batches={}}request(t){let r=this.options.batchBy(t);return r?(this.batches[r]||(this.batches[r]=[],this.tickActive||(this.tickActive=!0,process.nextTick(()=>{this.dispatchBatches(),this.tickActive=!1}))),new Promise((n,i)=>{this.batches[r].push({request:t,resolve:n,reject:i})})):this.options.singleLoader(t)}dispatchBatches(){for(let t in this.batches){let r=this.batches[t];delete this.batches[t],r.length===1?this.options.singleLoader(r[0].request).then(n=>{n instanceof Error?r[0].reject(n):r[0].resolve(n)}).catch(n=>{r[0].reject(n)}):this.options.batchLoader(r.map(n=>n.request)).then(n=>{if(n instanceof Error)for(let i=0;i<r.length;i++)r[i].reject(n);else for(let i=0;i<r.length;i++){let o=n[i];o instanceof Error?r[i].reject(o):r[i].resolve(o)}}).catch(n=>{for(let i=0;i<r.length;i++)r[i].reject(n)})}}get[Symbol.toStringTag](){return"DataLoader"}};a(pn,"DataLoader");var Lh=U("prisma:client:request_handler"),fn=class{constructor(t,r){this.logEmitter=r,this.client=t,this.dataloader=new pn({batchLoader:n=>{let i=n[0].transaction,s=n[0].protocolEncoder.createBatch(n.map(c=>c.protocolMessage)),l=De({context:n[0].otelParentCtx,tracingConfig:t._tracingConfig}),u=n.some(c=>c.protocolMessage.isWrite());return this.client._engine.requestBatch(s,{traceparent:l,transaction:jh(i),containsWrite:u,customDataProxyFetch:n[0].customDataProxyFetch})},singleLoader:n=>{let i=n.transaction?.kind==="itx"?Lc(n.transaction):void 0;return this.client._engine.request(n.protocolMessage.toEngineQuery(),{traceparent:De({tracingConfig:n.tracingConfig}),interactiveTransaction:i,isWrite:n.protocolMessage.isWrite(),customDataProxyFetch:n.customDataProxyFetch})},batchBy:n=>n.transaction?.id?`transaction-${n.transaction.id}`:n.protocolMessage.getBatchId()})}async request({protocolMessage:t,protocolEncoder:r,dataPath:n=[],callsite:i,modelName:o,rejectOnNotFound:s,clientMethod:l,args:u,transaction:c,unpacker:p,extensions:f,otelParentCtx:d,otelChildCtx:m,customDataProxyFetch:h}){try{let g=await this.dataloader.request({protocolMessage:t,protocolEncoder:r,transaction:c,otelParentCtx:d,otelChildCtx:m,tracingConfig:this.client._tracingConfig,customDataProxyFetch:h}),b=g?.data,y=g?.elapsed,x=this.unpack(t,b,n,p);return nc(x,l,o,s),o&&(x=this.applyResultExtensions({result:x,modelName:o,args:u,extensions:f})),process.env.PRISMA_CLIENT_GET_TIME?{data:x,elapsed:y}:x}catch(g){this.handleAndLogRequestError({error:g,clientMethod:l,callsite:i,transaction:c,args:u})}}handleAndLogRequestError(t){try{this.handleRequestError(t)}catch(r){throw this.logEmitter&&this.logEmitter.emit("error",{message:r.message,target:t.clientMethod,timestamp:new Date}),r}}handleRequestError({error:t,clientMethod:r,callsite:n,transaction:i,args:o}){if(Lh(t),Bh(t,i)||t instanceof Pe)throw t;if(t instanceof X&&qh(t)){let l=jc(t.meta);Ri({args:o,errors:[l],callsite:n,errorFormat:this.client._errorFormat,originalMethod:r})}let s=t.message;throw n&&(s=ct({callsite:n,originalMethod:r,isPanic:t.isPanic,showColors:this.client._errorFormat==="pretty",message:s})),s=this.sanitizeMessage(s),t.code?new X(s,{code:t.code,clientVersion:this.client._clientVersion,meta:t.meta,batchRequestIdx:t.batchRequestIdx}):t.isPanic?new fe(s,this.client._clientVersion):t instanceof Z?new Z(s,{clientVersion:this.client._clientVersion,batchRequestIdx:t.batchRequestIdx}):t instanceof G?new G(s,this.client._clientVersion):t instanceof fe?new fe(s,this.client._clientVersion):(t.clientVersion=this.client._clientVersion,t)}sanitizeMessage(t){return this.client._errorFormat&&this.client._errorFormat!=="pretty"?(0,$c.default)(t):t}unpack(t,r,n,i){if(!r)return r;r.data&&(r=r.data);let o=t.deserializeResponse(r,n);return i?i(o):o}applyResultExtensions({result:t,modelName:r,args:n,extensions:i}){if(i.isEmpty()||t==null)return t;let o=this.client._baseDmmf.getModelMap()[r];return o?Fi({result:t,args:n??{},model:o,dmmf:this.client._baseDmmf,visitor(s,l,u){let c=Te(l.name);return Dc({result:s,modelName:c,select:u.select,extensions:i})}}):t}get[Symbol.toStringTag](){return"RequestHandler"}};a(fn,"RequestHandler");function jh(e){if(!!e){if(e.kind==="batch")return{kind:"batch",options:{isolationLevel:e.isolationLevel}};if(e.kind==="itx")return{kind:"itx",options:Lc(e)};Ge(e,"Unknown transaction kind")}}a(jh,"getTransactionOptions");function Lc(e){return{id:e.id,payload:e.payload}}a(Lc,"getItxTransactionOptions");function Bh(e,t){return Br(e)&&t?.kind==="batch"&&e.batchRequestIdx!==t.index}a(Bh,"isMismatchingBatchIndex");function qh(e){return e.code==="P2009"||e.code==="P2012"}a(qh,"isValidationError");function jc(e){if(e.kind==="Union")return{kind:"Union",errors:e.errors.map(jc)};if(Array.isArray(e.selectionPath)){let[,...t]=e.selectionPath;return{...e,selectionPath:t}}return e}a(jc,"convertValidationError");function Bc(e){return e.map(t=>{let r={};for(let n of Object.keys(t))r[n]=qc(t[n]);return r})}a(Bc,"deserializeRawResults");function qc({prisma__type:e,prisma__value:t}){switch(e){case"bigint":return BigInt(t);case"bytes":return Buffer.from(t,"base64");case"decimal":return new ye(t);case"datetime":case"date":return new Date(t);case"time":return new Date(`1970-01-01T${t}Z`);case"array":return t.map(qc);default:return t}}a(qc,"deserializeValue");var Qc=O(Rn());var Vc=["datasources","errorFormat","log","__internal","rejectOnNotFound"],Uc=["pretty","colorless","minimal"],Gc=["info","query","warn","error"],Vh={datasources:(e,t)=>{if(!!e){if(typeof e!="object"||Array.isArray(e))throw new K(`Invalid value ${JSON.stringify(e)} for "datasources" provided to PrismaClient constructor`);for(let[r,n]of Object.entries(e)){if(!t.includes(r)){let i=ar(r,t)||`Available datasources: ${t.join(", ")}`;throw new K(`Unknown datasource ${r} provided to PrismaClient constructor.${i}`)}if(typeof n!="object"||Array.isArray(n))throw new K(`Invalid value ${JSON.stringify(e)} for datasource "${r}" provided to PrismaClient constructor.
2023-12-31T23:07:30.562613972Z                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             
2023-12-31T23:07:30.562623122Z 
2023-12-31T23:07:30.562626312Z PrismaClientKnownRequestError: 
2023-12-31T23:07:30.562629392Z Invalid `prisma.user.create()` invocation:
2023-12-31T23:07:30.562632652Z 
2023-12-31T23:07:30.562635522Z 
2023-12-31T23:07:30.562638382Z Unique constraint failed on the fields: (`username`)
2023-12-31T23:07:30.562641522Z     at fn.handleRequestError (/home/node/hemmelig/node_modules/@prisma/client/runtime/library.js:174:6477)
2023-12-31T23:07:30.562646272Z     at fn.handleAndLogRequestError (/home/node/hemmelig/node_modules/@prisma/client/runtime/library.js:174:5907)
2023-12-31T23:07:30.562649532Z     at fn.request (/home/node/hemmelig/node_modules/@prisma/client/runtime/library.js:174:5786)
2023-12-31T23:07:30.562652692Z     at async t._request (/home/node/hemmelig/node_modules/@prisma/client/runtime/library.js:177:10477)
2023-12-31T23:07:30.562655832Z     at async createRootUser (file:///home/node/hemmelig/src/server/bootstrap.js:48:5) {
2023-12-31T23:07:30.562659032Z   code: 'P2002',
2023-12-31T23:07:30.562661982Z   clientVersion: '4.12.0',
2023-12-31T23:07:30.562664942Z   meta: { target: [ 'username' ] }
2023-12-31T23:07:30.562667922Z }
2023-12-31T23:07:30.562670792Z 
2023-12-31T23:07:30.562673622Z Node.js v18.19.0
2023-12-31T23:07:30.572111234Z npm notice 
2023-12-31T23:07:30.572180485Z npm notice New patch version of npm available! 10.2.3 -> 10.2.5
2023-12-31T23:07:30.572477096Z npm notice Changelog: <https://github.com/npm/cli/releases/tag/v10.2.5>
2023-12-31T23:07:30.572529927Z npm notice Run `npm install -g npm@10.2.5` to update!
2023-12-31T23:07:30.572701788Z npm notice 

Screenshots

No response

Additional information

No response

bjarneo commented 8 months ago

Do this happen only for the newest version?

tryallthethings commented 8 months ago

I was running the exact same configuration with the previous release and didn't see this issue there.

bjarneo commented 7 months ago

I am quite not sure why this is happening to you. Tried to upgrade my own instance to the latest release without any issue, 🤔

tryallthethings commented 7 months ago

But did you have the same env variables for creating the root user as well?

bjarneo commented 7 months ago

Yes, I never change those. But that user will only be created on the first run. Not each time you restart / start the container. As long as the database is mounted correctly

tryallthethings commented 7 months ago

I can pretty much force the error by adding the env values back and restart the container. Can we get additional logs to debug this?

bjarneo commented 7 months ago

Sure. Can you open a PR and add the logs you need?

tryallthethings commented 7 months ago

I have no clue how to debug this. I was asking if we can enable some additional logging, so one of the devs can look into it.

bjarneo commented 7 months ago

There are no more logs to enable. It has to be manually added to the code. What devs? This is an open source tool mainly maintained by me. Occasionally people are contributing to the project.

bjarneo commented 7 months ago

Did you try to move the database and let the instance create a fresh one? To verify if that solves the issue. This seems to be not related to the application itself, but the data saved to the database.

bjarneo commented 7 months ago

I managed to reproduce this when testing locally:

  1. I was signed in with the default user and password
  2. I fetched the production database (which does not contain that user)
  3. Tried to create a secret.

What happens on 3. is that when you try to create a secret, and you are signed in with a user that does not exist in the database, then it tries to attach your user to the secret -> to the database. The matching will fail.

tryallthethings commented 7 months ago

I just tested it with the latest version and the issue is gone now. You might be correct with your assumption, as I had trouble with the database and kept recreating it while still being signed in with the old version. Good catch and thanks!