JavascriptMick
JavascriptMick
TtRPC
Created by JavascriptMick on 6/2/2023 in #❓-help
Use onError to change an application error into a TRPCError?
8 replies
TtRPC
Created by JavascriptMick on 6/2/2023 in #❓-help
Use onError to change an application error into a TRPCError?
ah nice, thanks guys, yep this works.....
const t = initTRPC.context<Context>().create({
errorFormatter: (opts)=> {
const { shape, error } = opts;
if (!(error.cause instanceof AccountLimitError)) {
return shape;
}
return {
...shape,
data: {
...shape.data,
httpStatus: 401,
code: 'UNAUTHORIZED'
},
};
}
})
const t = initTRPC.context<Context>().create({
errorFormatter: (opts)=> {
const { shape, error } = opts;
if (!(error.cause instanceof AccountLimitError)) {
return shape;
}
return {
...shape,
data: {
...shape.data,
httpStatus: 401,
code: 'UNAUTHORIZED'
},
};
}
})
8 replies
TtRPC
Created by JavascriptMick on 2/25/2023 in #❓-help
is context cached?
aha, thanks @msalsbery you are right, I accidentally introduced 'caching' because I am defining the variable for dbUser outside the createContext function.....
let dbUser: FullDBUser | null

export async function createContext(event: H3Event){
if (!dbUser) {....etc
let dbUser: FullDBUser | null

export async function createContext(event: H3Event){
if (!dbUser) {....etc
..... which in hindsight is REALLY STOOPID, the example I followed treated the db connection (i.e.. prisma) in this way but then loaded the user fresh on each call to context... this is the way.
7 replies
TtRPC
Created by JavascriptMick on 2/25/2023 in #❓-help
is context cached?
seems like createContext is indeed called for every request but the values on the context are already present on subsequent requests
7 replies
TtRPC
Created by JavascriptMick on 2/23/2023 in #❓-help
Best way to implement input based validation on a router procedure
for reference, this is what I ended up with...
/**
* auth middlewares
**/
const isAuthed = t.middleware(({ next, ctx }) => {
if (!ctx.user) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
return next({
ctx: {
user: ctx.user,
},
});
});

const isAdminForInputAccountId = t.middleware(({ next, rawInput, ctx }) => {
if (!ctx.dbUser) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
const result = z.object({ account_id: z.number() }).safeParse(rawInput);
if (!result.success) throw new TRPCError({ code: 'BAD_REQUEST' });
const { account_id } = result.data;
const test_membership = ctx.dbUser.memberships.find(membership => membership.account_id == account_id);
if(!test_membership || (test_membership?.access !== ACCOUNT_ACCESS.ADMIN && test_membership?.access !== ACCOUNT_ACCESS.OWNER)) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}

return next({ ctx });
});

export const publicProcedure = t.procedure;
export const protectedProcedure = t.procedure.use(isAuthed);
export const adminProcedure = protectedProcedure.use(isAdminForInputAccountId);
/**
* auth middlewares
**/
const isAuthed = t.middleware(({ next, ctx }) => {
if (!ctx.user) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
return next({
ctx: {
user: ctx.user,
},
});
});

const isAdminForInputAccountId = t.middleware(({ next, rawInput, ctx }) => {
if (!ctx.dbUser) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}
const result = z.object({ account_id: z.number() }).safeParse(rawInput);
if (!result.success) throw new TRPCError({ code: 'BAD_REQUEST' });
const { account_id } = result.data;
const test_membership = ctx.dbUser.memberships.find(membership => membership.account_id == account_id);
if(!test_membership || (test_membership?.access !== ACCOUNT_ACCESS.ADMIN && test_membership?.access !== ACCOUNT_ACCESS.OWNER)) {
throw new TRPCError({ code: 'UNAUTHORIZED' });
}

return next({ ctx });
});

export const publicProcedure = t.procedure;
export const protectedProcedure = t.procedure.use(isAuthed);
export const adminProcedure = protectedProcedure.use(isAdminForInputAccountId);
15 replies
TtRPC
Created by JavascriptMick on 2/23/2023 in #❓-help
Best way to implement input based validation on a router procedure
#win win
15 replies
TtRPC
Created by JavascriptMick on 2/23/2023 in #❓-help
Best way to implement input based validation on a router procedure
15 replies
TtRPC
Created by JavascriptMick on 2/23/2023 in #❓-help
Best way to implement input based validation on a router procedure
@Nick Lucas you may find this disconcerting but I was asking chatgpt the same question and shared our conversation.... and the combination of your context yielded a perfect answer...
15 replies
TtRPC
Created by JavascriptMick on 2/23/2023 in #❓-help
Best way to implement input based validation on a router procedure
Maybe, the 'active' account should be a session property and then the middleware approach might work better
15 replies
TtRPC
Created by JavascriptMick on 2/23/2023 in #❓-help
Best way to implement input based validation on a router procedure
Thanks Nick, that makes sense but I am trying to implement a multi-tenant model where a single user can be a member of multiple accounts so when a request comes in to mess around with accounts, the request includes the id of the account and the current users access within that account is therefore dependent on the input parameters.... maybe I am completely off the track here, what do you think?
15 replies