migs
migs
Explore posts from servers
DTDrizzle Team
Created by migs on 6/14/2024 in #help
TypeError: Cannot read properties of undefined (reading 'columns') - SQLite TursoDB
@Genio
8 replies
DTDrizzle Team
Created by Genio on 6/24/2024 in #help
[ERROR] TypeError: Cannot read properties of undefined (reading 'toString')
We might have different problems, if you check my thread, I have also defined the relations with the drizzle api
17 replies
DTDrizzle Team
Created by Genio on 6/24/2024 in #help
[ERROR] TypeError: Cannot read properties of undefined (reading 'toString')
Don't know if it's just with sqlite/turso but lately I've been having a lot of problems with migrations
17 replies
DTDrizzle Team
Created by migs on 6/14/2024 in #help
TypeError: Cannot read properties of undefined (reading 'columns') - SQLite TursoDB
8 replies
DTDrizzle Team
Created by Kenpaffu on 6/16/2024 in #help
SQLITE error "Table already exists"
Same problem here, also getting problems using db:push with a new table with foreign keys
3 replies
DTDrizzle Team
Created by The Fabulous Geek on 6/15/2024 in #help
Automating migration
The correct way of doing this is to generate the migration files locally, commit them and have the the migrations being run on your CI/CD
2 replies
DTDrizzle Team
Created by migs on 6/14/2024 in #help
TypeError: Cannot read properties of undefined (reading 'columns') - SQLite TursoDB
Looks like if I push without the foreign keys, it works, and if I add the foreign keys after the table already exists it will work. The problem seems to happen when you create a table with foreign keys from the beggining
8 replies
DTDrizzle Team
Created by migs on 6/14/2024 in #help
TypeError: Cannot read properties of undefined (reading 'columns') - SQLite TursoDB
This is the table I added that causes the problem, I might be missing something but I don't see anything wrong in it. If I remove this table and push again it will correctly apply changes, but I can't push when I add this table. Must be something wrong on this table
export const discountUses = sqLiteTable(
"discountUse",
{
id: integer("id", { mode: "number" }).primaryKey({ autoIncrement: true }),
discountId: integer("discountId")
.references(() => storeDiscounts.id, {
onDelete: "cascade",
})
.notNull(),
invoiceId: text("invoiceId")
.references(() => storeInvoices.id, {
onDelete: "cascade",
})
.notNull(),
},
(discountUse) => ({
discountUse_id_idxIdIdx: index("discountUse_id_idx").on(discountUse.id),
}),
);

export const discountUsesRelations = relations(discountUses, ({ one }) => ({
discount: one(storeDiscounts, {
fields: [discountUses.discountId],
references: [storeDiscounts.id],
}),
invoice: one(storeInvoices, {
fields: [discountUses.invoiceId],
references: [storeInvoices.id],
}),
}));
export const discountUses = sqLiteTable(
"discountUse",
{
id: integer("id", { mode: "number" }).primaryKey({ autoIncrement: true }),
discountId: integer("discountId")
.references(() => storeDiscounts.id, {
onDelete: "cascade",
})
.notNull(),
invoiceId: text("invoiceId")
.references(() => storeInvoices.id, {
onDelete: "cascade",
})
.notNull(),
},
(discountUse) => ({
discountUse_id_idxIdIdx: index("discountUse_id_idx").on(discountUse.id),
}),
);

export const discountUsesRelations = relations(discountUses, ({ one }) => ({
discount: one(storeDiscounts, {
fields: [discountUses.discountId],
references: [storeDiscounts.id],
}),
invoice: one(storeInvoices, {
fields: [discountUses.invoiceId],
references: [storeInvoices.id],
}),
}));
8 replies
DTDrizzle Team
Created by g0053 on 4/19/2024 in #help
Drizzle Kit Studio: Object is not iterable
all fixed on my side too. The only small detail I've noticed is that the db:push always says "Changes Applied" even when there's no changes. It used to be able to distinguish this
25 replies
DTDrizzle Team
Created by migs on 4/21/2024 in #help
Field 'email' doesn't have a default with connection pool in MySQL
Fixed it. I had a custom scope on next auth for discord that was missing the email scope. Removed it so it uses the default scopes
2 replies
DTDrizzle Team
Created by g0053 on 4/19/2024 in #help
Drizzle Kit Studio: Object is not iterable
for some reason its still not fixed for me, maybe pnpm is caching something from the previous one and I just updated to 20.17
25 replies
TTCTheo's Typesafe Cult
Created by migs on 1/31/2024 in #questions
TRPC Security/ Authorization Concerns
I'll edit it above, thank you!
13 replies
TTCTheo's Typesafe Cult
Created by migs on 1/31/2024 in #questions
TRPC Security/ Authorization Concerns
This was incredibly helpful, thank you so much @andersgee Inspired by this, I came up with the solution I think fits this best. Still based on cody's project so others can understand it better here's what I ended up with:
const userHasClassroomAccess = async ({
classroomId,
ctx,
}: {
classroomId: string;
ctx: {
session: Session | null;
db: PlanetScaleDatabase<typeof import("../db/schema")>;
};
}) => {
//this logic will depend a lot on your schema

const classroom = await ctx.db.query.classrooms.findFirst({
where: eq(classrooms.id, classroomId),
});

if (classroomId?.ownerId === ctx.session?.user.id) return true;

return false;
};
const userHasClassroomAccess = async ({
classroomId,
ctx,
}: {
classroomId: string;
ctx: {
session: Session | null;
db: PlanetScaleDatabase<typeof import("../db/schema")>;
};
}) => {
//this logic will depend a lot on your schema

const classroom = await ctx.db.query.classrooms.findFirst({
where: eq(classrooms.id, classroomId),
});

if (classroomId?.ownerId === ctx.session?.user.id) return true;

return false;
};
This part was what unlocked my brain mostly, I didn't know that I could easily get the input from the request here (finally read trpc documentation lol). This works perfectly for my case, since I was already sending the classroomId as input to all the procedures I needed, just like Cody is doing on the video. Note: Be careful with the input, rawInput means that it hasn't been validated with zod yet, so we validate here.
const enforceUserHasClassroomAccess = t.middleware(
async ({ ctx, next, rawInput }) => {
const { classroomId } = z.object({ classroomId: z.number() }).parse(rawInput);

if (!ctx.session?.user || !classroomId) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}

const hasAccess = await userHasClassroomAccess({
classroomId: classroomId,
ctx: ctx,
});

if (!hasAccess) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}

return next({
ctx: {
// infers the `session` as non-nullable
session: { ...ctx.session, user: ctx.session.user },
},
});
},
);
const enforceUserHasClassroomAccess = t.middleware(
async ({ ctx, next, rawInput }) => {
const { classroomId } = z.object({ classroomId: z.number() }).parse(rawInput);

if (!ctx.session?.user || !classroomId) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}

const hasAccess = await userHasClassroomAccess({
classroomId: classroomId,
ctx: ctx,
});

if (!hasAccess) {
throw new TRPCError({ code: "UNAUTHORIZED" });
}

return next({
ctx: {
// infers the `session` as non-nullable
session: { ...ctx.session, user: ctx.session.user },
},
});
},
);
export const withClassroomAccessProcedure = t.procedure.use(
enforceUserHasClassroomAccess
);
export const withClassroomAccessProcedure = t.procedure.use(
enforceUserHasClassroomAccess
);
13 replies
TTCTheo's Typesafe Cult
Created by migs on 1/31/2024 in #questions
TRPC Security/ Authorization Concerns
Cody is in a very similar situation to mine in this video https://youtu.be/I5UXsAW9dUE?si=mGjih6SBAtJT3FNG I don't really like the way he solves this since we could always forget to add that assertion. Given this example from Cody, would it make sense to have the classroomId in the session, and change it based on the classroom you're currently managing so we could then access the classroomId in the trpc procedures ?
13 replies
TTCTheo's Typesafe Cult
Created by migs on 1/31/2024 in #questions
TRPC Security/ Authorization Concerns
That was a very good explanation. Made me realize that what I need to do, is add more data to my session object, and use that value on the calls, instead of just receiving as an input
13 replies
TTCTheo's Typesafe Cult
Created by migs on 1/31/2024 in #questions
TRPC Security/ Authorization Concerns
But also, my authorization rules will not be too complex, I was thinking of creating a table for authorizations and querying my db in the context, but not sure if this is a good thing to do
13 replies
TTCTheo's Typesafe Cult
Created by migs on 1/31/2024 in #questions
TRPC Security/ Authorization Concerns
Thanks for the suggestion, unfortunately I'm using drizzle and casl doesn't seem to have a package for drizzle, same with zenstack. Is there a good alternative for drizzle ?
13 replies