2024-09-26 19:02:45 +02:00
|
|
|
import dayjs from "dayjs";
|
2024-02-10 19:00:08 +01:00
|
|
|
import type { NextAuthConfig } from "next-auth";
|
|
|
|
|
|
2024-10-05 16:18:31 +02:00
|
|
|
import type { Session } from "@homarr/auth";
|
2024-05-04 18:34:41 +02:00
|
|
|
import type { Database } from "@homarr/db";
|
|
|
|
|
import { eq, inArray } from "@homarr/db";
|
2024-12-19 16:10:22 +01:00
|
|
|
import { groupMembers, groupPermissions, users } from "@homarr/db/schema";
|
2024-05-04 18:34:41 +02:00
|
|
|
import { getPermissionsWithChildren } from "@homarr/definitions";
|
|
|
|
|
|
2024-05-19 22:38:39 +02:00
|
|
|
export const getCurrentUserPermissionsAsync = async (db: Database, userId: string) => {
|
2024-05-04 18:34:41 +02:00
|
|
|
const dbGroupMembers = await db.query.groupMembers.findMany({
|
|
|
|
|
where: eq(groupMembers.userId, userId),
|
|
|
|
|
});
|
|
|
|
|
const groupIds = dbGroupMembers.map((groupMember) => groupMember.groupId);
|
2024-07-08 17:39:36 +02:00
|
|
|
|
|
|
|
|
if (groupIds.length === 0) return [];
|
|
|
|
|
|
2024-05-04 18:34:41 +02:00
|
|
|
const dbGroupPermissions = await db
|
|
|
|
|
.selectDistinct({
|
|
|
|
|
permission: groupPermissions.permission,
|
|
|
|
|
})
|
|
|
|
|
.from(groupPermissions)
|
2024-07-08 17:39:36 +02:00
|
|
|
.where(inArray(groupPermissions.groupId, groupIds));
|
2024-05-04 18:34:41 +02:00
|
|
|
const permissionKeys = dbGroupPermissions.map(({ permission }) => permission);
|
|
|
|
|
|
|
|
|
|
return getPermissionsWithChildren(permissionKeys);
|
|
|
|
|
};
|
|
|
|
|
|
2024-10-05 16:18:31 +02:00
|
|
|
export const createSessionAsync = async (
|
|
|
|
|
db: Database,
|
|
|
|
|
user: { id: string; email: string | null },
|
|
|
|
|
): Promise<Session> => {
|
|
|
|
|
return {
|
|
|
|
|
expires: dayjs().add(1, "day").toISOString(),
|
|
|
|
|
user: {
|
|
|
|
|
...user,
|
|
|
|
|
email: user.email ?? "",
|
|
|
|
|
permissions: await getCurrentUserPermissionsAsync(db, user.id),
|
2024-10-16 21:44:53 +02:00
|
|
|
colorScheme: "dark",
|
2024-10-05 16:18:31 +02:00
|
|
|
},
|
|
|
|
|
} as Session;
|
|
|
|
|
};
|
|
|
|
|
|
2024-05-19 22:38:39 +02:00
|
|
|
export const createSessionCallback = (db: Database): NextAuthCallbackOf<"session"> => {
|
2024-05-04 18:34:41 +02:00
|
|
|
return async ({ session, user }) => {
|
2024-09-01 20:37:52 +02:00
|
|
|
const additionalProperties = await db.query.users.findFirst({
|
|
|
|
|
where: eq(users.id, user.id),
|
|
|
|
|
columns: {
|
|
|
|
|
colorScheme: true,
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
2024-05-04 18:34:41 +02:00
|
|
|
return {
|
|
|
|
|
...session,
|
|
|
|
|
user: {
|
|
|
|
|
...session.user,
|
2024-09-01 20:37:52 +02:00
|
|
|
...additionalProperties,
|
2024-05-04 18:34:41 +02:00
|
|
|
id: user.id,
|
|
|
|
|
name: user.name,
|
2024-05-18 12:25:33 +02:00
|
|
|
permissions: await getCurrentUserPermissionsAsync(db, user.id),
|
2024-05-04 18:34:41 +02:00
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
};
|
|
|
|
|
};
|
2024-02-10 19:00:08 +01:00
|
|
|
|
|
|
|
|
type NextAuthCallbackRecord = Exclude<NextAuthConfig["callbacks"], undefined>;
|
2024-05-19 22:38:39 +02:00
|
|
|
export type NextAuthCallbackOf<TKey extends keyof NextAuthCallbackRecord> = Exclude<
|
|
|
|
|
NextAuthCallbackRecord[TKey],
|
|
|
|
|
undefined
|
|
|
|
|
>;
|