aboutsummaryrefslogtreecommitdiffstats
path: root/web/lib
diff options
context:
space:
mode:
Diffstat (limited to 'web/lib')
-rw-r--r--web/lib/auth.ts25
-rw-r--r--web/lib/config.ts20
-rw-r--r--web/lib/prisma.ts5
-rw-r--r--web/lib/types/api/links.ts26
-rw-r--r--web/lib/types/next-auth.d.ts12
-rw-r--r--web/lib/utils.ts6
6 files changed, 94 insertions, 0 deletions
diff --git a/web/lib/auth.ts b/web/lib/auth.ts
new file mode 100644
index 00000000..9b21e605
--- /dev/null
+++ b/web/lib/auth.ts
@@ -0,0 +1,25 @@
+import NextAuth, { NextAuthOptions } from "next-auth"
+import { PrismaAdapter } from "@next-auth/prisma-adapter"
+import AuthentikProvider from "next-auth/providers/authentik";
+import serverConfig from "@/lib/config";
+import prisma from "@/lib/prisma";
+
+let providers = [];
+
+if (serverConfig.auth.authentik) {
+ providers.push(AuthentikProvider(serverConfig.auth.authentik));
+}
+
+export const authOptions: NextAuthOptions = {
+ // Configure one or more authentication providers
+ adapter: PrismaAdapter(prisma),
+ providers: providers,
+ callbacks: {
+ session({ session, token, user }) {
+ session.user = { ...user };
+ return session;
+ }
+ }
+};
+
+export const authHandler = NextAuth(authOptions);
diff --git a/web/lib/config.ts b/web/lib/config.ts
new file mode 100644
index 00000000..ef86cb5a
--- /dev/null
+++ b/web/lib/config.ts
@@ -0,0 +1,20 @@
+function buildAuthentikConfig() {
+ let {id, secret, issuer} = process.env;
+ if (!id || !secret || !issuer) {
+ return undefined;
+ }
+
+ return {
+ clientId: id,
+ clientSecret: secret,
+ issuer: issuer,
+ };
+}
+
+const serverConfig = {
+ auth: {
+ authentik: buildAuthentikConfig(),
+ }
+};
+
+export default serverConfig;
diff --git a/web/lib/prisma.ts b/web/lib/prisma.ts
new file mode 100644
index 00000000..d73ba5f2
--- /dev/null
+++ b/web/lib/prisma.ts
@@ -0,0 +1,5 @@
+import { PrismaClient } from '@prisma/client'
+
+const prisma = new PrismaClient();
+
+export default prisma;
diff --git a/web/lib/types/api/links.ts b/web/lib/types/api/links.ts
new file mode 100644
index 00000000..81cde053
--- /dev/null
+++ b/web/lib/types/api/links.ts
@@ -0,0 +1,26 @@
+import { z } from "zod";
+
+export const ZBookmarkedLink = z.object({
+ id: z.string(),
+ url: z.string().url(),
+ createdAt: z.coerce.date(),
+
+ details: z.object({
+ title: z.string(),
+ description: z.string(),
+ imageUrl: z.string().url(),
+ }).nullish(),
+
+});
+export type ZBookmarkedLink = z.infer<typeof ZBookmarkedLink>;
+
+
+// POST /v1/links
+export const ZNewBookmarkedLinkRequest = ZBookmarkedLink.pick({ url: true });
+
+
+// GET /v1/links
+export const ZGetLinksResponse = z.object({
+ links: z.array(ZBookmarkedLink),
+});
+export type ZGetLinksResponse = z.infer<typeof ZGetLinksResponse>;
diff --git a/web/lib/types/next-auth.d.ts b/web/lib/types/next-auth.d.ts
new file mode 100644
index 00000000..bdd3bd03
--- /dev/null
+++ b/web/lib/types/next-auth.d.ts
@@ -0,0 +1,12 @@
+import NextAuth, { DefaultSession } from "next-auth"
+
+declare module "next-auth" {
+ /**
+ * Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context
+ */
+ interface Session {
+ user: {
+ id: string;
+ } & DefaultSession["user"];
+ }
+}
diff --git a/web/lib/utils.ts b/web/lib/utils.ts
new file mode 100644
index 00000000..d084ccad
--- /dev/null
+++ b/web/lib/utils.ts
@@ -0,0 +1,6 @@
+import { type ClassValue, clsx } from "clsx"
+import { twMerge } from "tailwind-merge"
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs))
+}