diff --git a/README.md b/README.md
index bb5a4853..7dcb6dd8 100755
--- a/README.md
+++ b/README.md
@@ -118,11 +118,11 @@ OAUTH_GITHUB_CLIENT_SECRET=x
OAUTH_GOOGLE_CLIENT_ID=x-x.apps.googleusercontent.com
OAUTH_GOOGLE_CLIENT_SECRET=x-x-x
-OAUTH_AUTHENTIK_CLIENT_ID=x
-OAUTH_AUTHENTIK_CLIENT_SECRET=x
-OAUTH_AUTHENTIK_AUTHORIZE_URL=http://localhost:9000/application/o/authorize/
-OAUTH_AUTHENTIK_USERINFO_URL=http://localhost:9000/application/o/userinfo/
-OAUTH_AUTHENTIK_TOKEN_URL=http://localhost:9000/application/o/token/
+OAUTH_OIDC_CLIENT_ID=x
+OAUTH_OIDC_CLIENT_SECRET=x
+OAUTH_OIDC_AUTHORIZE_URL=http://localhost:9000/application/o/authorize/
+OAUTH_OIDC_USERINFO_URL=http://localhost:9000/application/o/userinfo/
+OAUTH_OIDC_TOKEN_URL=http://localhost:9000/application/o/token/
FEATURES_OAUTH_REGISTRATION=true
FEATURES_USER_REGISTRATION=true
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 69ecb664..7e335489 100755
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -29,6 +29,7 @@ model User {
totpSecret String?
passkeys UserPasskey[]
+ sessions String[]
quota UserQuota?
@@ -103,7 +104,7 @@ enum OAuthProviderType {
DISCORD
GOOGLE
GITHUB
- AUTHENTIK
+ OIDC
}
model File {
@@ -112,7 +113,7 @@ model File {
updatedAt DateTime @updatedAt
deletesAt DateTime?
- name String // name & file saved on datasource
+ name String // name & file saved on datasource
originalName String? // original name of file when uploaded
size BigInt
type String
@@ -232,4 +233,4 @@ model Invite {
inviter User @relation(fields: [inviterId], references: [id], onDelete: Cascade, onUpdate: Cascade)
inviterId String
-}
+}
\ No newline at end of file
diff --git a/src/components/pages/settings/parts/SettingsOAuth/index.tsx b/src/components/pages/settings/parts/SettingsOAuth/index.tsx
index b3a23c5f..4835ba07 100755
--- a/src/components/pages/settings/parts/SettingsOAuth/index.tsx
+++ b/src/components/pages/settings/parts/SettingsOAuth/index.tsx
@@ -24,14 +24,14 @@ const icons = {
DISCORD: ,
GITHUB: ,
GOOGLE: ,
- AUTHENTIK: ,
+ OIDC: ,
};
const names = {
DISCORD: 'Discord',
GITHUB: 'GitHub',
GOOGLE: 'Google',
- AUTHENTIK: 'Authentik',
+ OIDC: 'OpenID Connect',
};
function OAuthButton({ provider, linked }: { provider: OAuthProviderType; linked: boolean }) {
@@ -90,7 +90,7 @@ export default function SettingsOAuth() {
const discordLinked = findProvider('DISCORD', user?.oauthProviders ?? []);
const githubLinked = findProvider('GITHUB', user?.oauthProviders ?? []);
const googleLinked = findProvider('GOOGLE', user?.oauthProviders ?? []);
- const authentikLinked = findProvider('AUTHENTIK', user?.oauthProviders ?? []);
+ const oidcLinked = findProvider('OIDC', user?.oauthProviders ?? []);
return (
@@ -103,7 +103,7 @@ export default function SettingsOAuth() {
{config.oauthEnabled.discord && }
{config.oauthEnabled.github && }
{config.oauthEnabled.google && }
- {config.oauthEnabled.authentik && }
+ {config.oauthEnabled.oidc && }
);
diff --git a/src/lib/config/read.ts b/src/lib/config/read.ts
index 74ca82cb..cc73c171 100755
--- a/src/lib/config/read.ts
+++ b/src/lib/config/read.ts
@@ -102,7 +102,7 @@ export const rawConfig: any = {
clientId: undefined,
clientSecret: undefined,
},
- authentik: {
+ oidc: {
clientId: undefined,
clientSecret: undefined,
authorizeUrl: undefined,
@@ -211,11 +211,11 @@ export const PROP_TO_ENV = {
'oauth.github.clientSecret': 'OAUTH_GITHUB_CLIENT_SECRET',
'oauth.google.clientId': 'OAUTH_GOOGLE_CLIENT_ID',
'oauth.google.clientSecret': 'OAUTH_GOOGLE_CLIENT_SECRET',
- 'oauth.authentik.clientId': 'OAUTH_AUTHENTIK_CLIENT_ID',
- 'oauth.authentik.clientSecret': 'OAUTH_AUTHENTIK_CLIENT_SECRET',
- 'oauth.authentik.authorizeUrl': 'OAUTH_AUTHENTIK_AUTHORIZE_URL',
- 'oauth.authentik.userinfoUrl': 'OAUTH_AUTHENTIK_USERINFO_URL',
- 'oauth.authentik.tokenUrl': 'OAUTH_AUTHENTIK_TOKEN_URL',
+ 'oauth.oidc.clientId': 'OAUTH_OIDC_CLIENT_ID',
+ 'oauth.oidc.clientSecret': 'OAUTH_OIDC_CLIENT_SECRET',
+ 'oauth.oidc.authorizeUrl': 'OAUTH_OIDC_AUTHORIZE_URL',
+ 'oauth.oidc.userinfoUrl': 'OAUTH_OIDC_USERINFO_URL',
+ 'oauth.oidc.tokenUrl': 'OAUTH_OIDC_TOKEN_URL',
'discord.webhookUrl': 'DISCORD_WEBHOOK_URL',
'discord.username': 'DISCORD_USERNAME',
@@ -339,11 +339,11 @@ export function readEnv() {
env('oauth.github.clientSecret', 'string'),
env('oauth.google.clientId', 'string'),
env('oauth.google.clientSecret', 'string'),
- env('oauth.authentik.clientId', 'string'),
- env('oauth.authentik.clientSecret', 'string'),
- env('oauth.authentik.authorizeUrl', 'string'),
- env('oauth.authentik.userinfoUrl', 'string'),
- env('oauth.authentik.tokenUrl', 'string'),
+ env('oauth.oidc.clientId', 'string'),
+ env('oauth.oidc.clientSecret', 'string'),
+ env('oauth.oidc.authorizeUrl', 'string'),
+ env('oauth.oidc.userinfoUrl', 'string'),
+ env('oauth.oidc.tokenUrl', 'string'),
env('discord.webhookUrl', 'string'),
env('discord.username', 'string'),
diff --git a/src/lib/config/validate.ts b/src/lib/config/validate.ts
index b5b74675..3f897362 100755
--- a/src/lib/config/validate.ts
+++ b/src/lib/config/validate.ts
@@ -242,7 +242,7 @@ export const schema = z.object({
clientSecret: z.undefined(),
}),
),
- authentik: z
+ oidc: z
.object({
clientId: z.string(),
clientSecret: z.string(),
diff --git a/src/lib/db/models/user.ts b/src/lib/db/models/user.ts
index 5b489a8c..66e8d22f 100755
--- a/src/lib/db/models/user.ts
+++ b/src/lib/db/models/user.ts
@@ -9,6 +9,8 @@ export type User = {
role: 'USER' | 'ADMIN' | 'SUPERADMIN';
view: UserViewSettings;
+ sessions: string[];
+
oauthProviders: OAuthProvider[];
totpSecret?: string | null;
@@ -32,6 +34,7 @@ export const userSelect = {
totpSecret: true,
passkeys: true,
quota: true,
+ sessions: true,
};
export type UserViewSettings = z.infer;
diff --git a/src/lib/middleware/ziplineAuth.ts b/src/lib/middleware/ziplineAuth.ts
index bfe8aef1..4d6edced 100755
--- a/src/lib/middleware/ziplineAuth.ts
+++ b/src/lib/middleware/ziplineAuth.ts
@@ -6,6 +6,7 @@ import { User, userSelect } from '../db/models/user';
import { NextApiReq, NextApiRes } from '../response';
import { Handler } from './combine';
import { isAdministrator } from '../role';
+import { getSession } from '@/server/session';
export type ZiplineAuthOptions = {
administratorOnly?: boolean;
@@ -47,28 +48,19 @@ export function parseUserToken(
export function ziplineAuth(options?: ZiplineAuthOptions) {
return (handler: Handler) => {
return async (req: NextApiReq, res: NextApiRes) => {
- let rawToken: string | undefined;
-
- if (req.cookies.zipline_token) rawToken = req.cookies.zipline_token;
- else if (req.headers.authorization) rawToken = req.headers.authorization;
-
- try {
- // eslint-disable-next-line no-var
- var token = parseUserToken(rawToken);
- } catch (e) {
- return res.unauthorized((e as { error: string }).error);
- }
+ const session = await getSession(req, res);
+ if (!session.id || !session.sessionId) return res.unauthorized('invalid session, not logged in');
const user = await prisma.user.findFirst({
where: {
- token,
- },
- select: {
- ...userSelect,
- ...(options?.select && options.select),
+ sessions: {
+ has: session.sessionId,
+ },
},
+ select: userSelect,
});
- if (!user) return res.unauthorized();
+
+ if (!user) return res.unauthorized('invalid login session');
req.user = user;
diff --git a/src/lib/oauth/enabled.ts b/src/lib/oauth/enabled.ts
index f3f6dfdf..96bacf4b 100755
--- a/src/lib/oauth/enabled.ts
+++ b/src/lib/oauth/enabled.ts
@@ -20,12 +20,12 @@ export default function enabled(config: Config) {
config.features.oauthRegistration,
);
- const authentikEnabled = isTruthy(
- config.oauth?.authentik?.clientId,
- config.oauth?.authentik?.clientSecret,
- config.oauth?.authentik?.authorizeUrl,
- config.oauth?.authentik?.tokenUrl,
- config.oauth?.authentik?.userinfoUrl,
+ const oidcEnabled = isTruthy(
+ config.oauth?.oidc?.clientId,
+ config.oauth?.oidc?.clientSecret,
+ config.oauth?.oidc?.authorizeUrl,
+ config.oauth?.oidc?.tokenUrl,
+ config.oauth?.oidc?.userinfoUrl,
config.features.oauthRegistration,
);
@@ -33,6 +33,6 @@ export default function enabled(config: Config) {
discord: discordEnabled,
github: githubEnabled,
google: googleEnabled,
- authentik: authentikEnabled,
+ oidc: oidcEnabled,
};
}
diff --git a/src/lib/oauth/providerUtil.ts b/src/lib/oauth/providerUtil.ts
index 31e1d5e0..6d06e3a3 100755
--- a/src/lib/oauth/providerUtil.ts
+++ b/src/lib/oauth/providerUtil.ts
@@ -61,10 +61,10 @@ export const googleAuth = {
},
};
-export const authentikAuth = {
+export const oidcAuth = {
url: (clientId: string, origin: string, authorizeUrl: string, state?: string) =>
`${authorizeUrl}?client_id=${clientId}&redirect_uri=${encodeURIComponent(
- `${origin}/api/auth/oauth/authentik`,
+ `${origin}/api/auth/oauth/oidc`,
)}&response_type=code&scope=openid+email+profile+offline_access${state ? `&state=${state}` : ''}`,
user: async (accessToken: string, userInfoUrl: string) => {
const res = await fetch(userInfoUrl, {
diff --git a/src/lib/oauth/withOAuth.ts b/src/lib/oauth/withOAuth.ts
index 4535ee3a..bfed27be 100755
--- a/src/lib/oauth/withOAuth.ts
+++ b/src/lib/oauth/withOAuth.ts
@@ -1,13 +1,12 @@
import { NextApiReq, NextApiRes } from '@/lib/response';
import { OAuthProviderType } from '@prisma/client';
import { prisma } from '../db';
-import { parseUserToken } from '../middleware/ziplineAuth';
import { findProvider } from './providerUtil';
import { createToken } from '../crypto';
import { config } from '../config';
import { User } from '../db/models/user';
import Logger, { log } from '../logger';
-import { getSession } from '@/server/session';
+import { getSession, saveSession } from '@/server/session';
export interface OAuthQuery {
state?: string;
@@ -76,15 +75,11 @@ export const withOAuth =
const { state } = req.query as OAuthQuery;
- let rawToken: string | undefined;
-
- if (req.cookies.zipline_token) rawToken = req.cookies.zipline_token;
- else if (req.headers.authorization) rawToken = req.headers.authorization;
- const token = parseUserToken(rawToken, true);
-
const user = await prisma.user.findFirst({
where: {
- token: token ?? '',
+ sessions: {
+ has: session.sessionId ?? '',
+ },
},
include: {
oauthProviders: true,
@@ -94,7 +89,7 @@ export const withOAuth =
const userOauth = findProvider(provider, user?.oauthProviders ?? []);
if (state === 'link') {
- if (!user) return res.unauthorized();
+ if (!user) return res.unauthorized('invalid session');
if (findProvider(provider, user.oauthProviders))
return res.badRequest('This account is already linked to this provider');
@@ -122,8 +117,7 @@ export const withOAuth =
},
});
- session.user = user;
- await session.save();
+ await saveSession(session, user);
logger.info('linked oauth account', {
provider,
@@ -153,8 +147,7 @@ export const withOAuth =
},
});
- session.user = user;
- await session.save();
+ await saveSession(session, user);
return res.redirect('/dashboard');
} else if (existingOauth) {
@@ -173,8 +166,7 @@ export const withOAuth =
},
});
- session.user = login.user! as User;
- await session.save();
+ await saveSession(session, login.user!);
logger.info('logged in with oauth', {
provider,
@@ -206,8 +198,7 @@ export const withOAuth =
},
});
- session.user = nuser as User;
- await session.save();
+ await saveSession(session, nuser);
logger.info('created user with oauth', {
provider,
diff --git a/src/lib/theme/file.ts b/src/lib/theme/file.ts
index 651bc569..c763eada 100755
--- a/src/lib/theme/file.ts
+++ b/src/lib/theme/file.ts
@@ -69,7 +69,7 @@ export async function handleOverrideColors(theme: ZiplineTheme) {
...theme.colors,
google: theme.colors?.google || Array(10).fill('#4285F4'),
github: theme.colors?.github || Array(10).fill('#24292E'),
- authentik: theme.colors?.authentik || Array(10).fill('#FD4B2D'),
+ oidc: theme.colors?.oidc || Array(10).fill('#72abcf'),
discord: theme.colors?.discord || Array(10).fill('#5865F2'),
},
} as ZiplineTheme;
diff --git a/src/pages/api/auth/oauth/authentik.ts b/src/pages/api/auth/oauth/oidc.ts
old mode 100755
new mode 100644
similarity index 68%
rename from src/pages/api/auth/oauth/authentik.ts
rename to src/pages/api/auth/oauth/oidc.ts
index 84ba0560..11ef087b
--- a/src/pages/api/auth/oauth/authentik.ts
+++ b/src/pages/api/auth/oauth/oidc.ts
@@ -3,7 +3,7 @@ import Logger from '@/lib/logger';
import { combine } from '@/lib/middleware/combine';
import { method } from '@/lib/middleware/method';
import enabled from '@/lib/oauth/enabled';
-import { authentikAuth } from '@/lib/oauth/providerUtil';
+import { oidcAuth } from '@/lib/oauth/providerUtil';
import { OAuthQuery, OAuthResponse, withOAuth } from '@/lib/oauth/withOAuth';
// thanks to @danejur for this https://github.com/diced/zipline/pull/372
@@ -14,33 +14,33 @@ async function handler({ code, state, host }: OAuthQuery, _logger: Logger): Prom
error_code: 403,
};
- const { authentik: authentikEnabled } = enabled(config);
+ const { oidc: oidcEnabled } = enabled(config);
- if (!authentikEnabled)
+ if (!oidcEnabled)
return {
- error: 'Authentik OAuth is not configured.',
+ error: 'OpenID Connect OAuth is not configured.',
error_code: 401,
};
if (!code)
return {
- redirect: authentikAuth.url(
- config.oauth.authentik.clientId!,
+ redirect: oidcAuth.url(
+ config.oauth.oidc.clientId!,
`${config.core.returnHttpsUrls ? 'https' : 'http'}://${host}`,
- config.oauth.authentik.authorizeUrl!,
+ config.oauth.oidc.authorizeUrl!,
state,
),
};
const body = new URLSearchParams({
- client_id: config.oauth.authentik.clientId!,
- client_secret: config.oauth.authentik.clientSecret!,
+ client_id: config.oauth.oidc.clientId!,
+ client_secret: config.oauth.oidc.clientSecret!,
grant_type: 'authorization_code',
code,
- redirect_uri: `${config.core.returnHttpsUrls ? 'https' : 'http'}://${host}/api/auth/oauth/authentik`,
+ redirect_uri: `${config.core.returnHttpsUrls ? 'https' : 'http'}://${host}/api/auth/oauth/oidc`,
});
- const res = await fetch(config.oauth.authentik.tokenUrl!, {
+ const res = await fetch(config.oauth.oidc.tokenUrl!, {
method: 'POST',
body,
headers: {
@@ -57,7 +57,7 @@ async function handler({ code, state, host }: OAuthQuery, _logger: Logger): Prom
if (!json.access_token) return { error: 'No access token in response' };
if (!json.refresh_token) return { error: 'No refresh token in response' };
- const userJson = await authentikAuth.user(json.access_token, config.oauth.authentik.userinfoUrl!);
+ const userJson = await oidcAuth.user(json.access_token, config.oauth.oidc.userinfoUrl!);
if (!userJson) return { error: 'Failed to fetch user' };
return {
@@ -68,4 +68,4 @@ async function handler({ code, state, host }: OAuthQuery, _logger: Logger): Prom
};
}
-export default combine([method(['GET'])], withOAuth('AUTHENTIK', handler));
+export default combine([method(['GET'])], withOAuth('OIDC', handler));
diff --git a/src/pages/auth/login.tsx b/src/pages/auth/login.tsx
index fb0e7077..f4b491f4 100755
--- a/src/pages/auth/login.tsx
+++ b/src/pages/auth/login.tsx
@@ -332,8 +332,8 @@ export default function Login({ config }: InferGetServerSidePropsType}
/>
)}
- {config.oauthEnabled.authentik && (
- } />
+ {config.oauthEnabled.oidc && (
+ } />
)}
diff --git a/src/server/middleware/user.ts b/src/server/middleware/user.ts
index fb269df2..b676b580 100755
--- a/src/server/middleware/user.ts
+++ b/src/server/middleware/user.ts
@@ -41,11 +41,13 @@ export function parseUserToken(
export async function userMiddleware(req: FastifyRequest, res: FastifyReply) {
const session = await getSession(req, res);
- if (!session.user) return res.unauthorized('not logged in');
+ if (!session.id || !session.sessionId) return res.unauthorized('not logged in');
const user = await prisma.user.findFirst({
where: {
- password: session.user.password,
+ sessions: {
+ has: session.sessionId,
+ },
},
select: userSelect,
});
diff --git a/src/server/routes/api/auth/login.ts b/src/server/routes/api/auth/login.ts
index 3a8ebca8..94ee7fe1 100755
--- a/src/server/routes/api/auth/login.ts
+++ b/src/server/routes/api/auth/login.ts
@@ -2,7 +2,7 @@ import { verifyPassword } from '@/lib/crypto';
import { prisma } from '@/lib/db';
import { User, userSelect } from '@/lib/db/models/user';
import { verifyTotpCode } from '@/lib/totp';
-import { getSession } from '@/server/session';
+import { getSession, saveSession } from '@/server/session';
import fastifyPlugin from 'fastify-plugin';
export type ApiLoginResponse = {
@@ -27,7 +27,8 @@ export default fastifyPlugin(
handler: async (req, res) => {
const session = await getSession(req, res);
- session.user = null;
+ session.id = null;
+ session.sessionId = null;
const { username, password, code } = req.body;
@@ -60,8 +61,7 @@ export default fastifyPlugin(
totp: true,
});
- session.user = user;
- await session.save();
+ await saveSession(session, user as User, false);
delete (user as any).password;
diff --git a/src/server/routes/api/auth/register.ts b/src/server/routes/api/auth/register.ts
index a6dc0202..2be2c749 100755
--- a/src/server/routes/api/auth/register.ts
+++ b/src/server/routes/api/auth/register.ts
@@ -1,8 +1,8 @@
import { config } from '@/lib/config';
import { createToken, hashPassword } from '@/lib/crypto';
import { prisma } from '@/lib/db';
-import { userSelect } from '@/lib/db/models/user';
-import { getSession } from '@/server/session';
+import { User, userSelect } from '@/lib/db/models/user';
+import { getSession, saveSession } from '@/server/session';
import fastifyPlugin from 'fastify-plugin';
import { ApiLoginResponse } from './login';
@@ -76,8 +76,7 @@ export default fastifyPlugin(
},
});
- session.user = user;
- await session.save();
+ await saveSession(session, user);
delete (user as any).password;
diff --git a/src/server/routes/api/auth/webauthn.ts b/src/server/routes/api/auth/webauthn.ts
index 95926576..45cc33ba 100755
--- a/src/server/routes/api/auth/webauthn.ts
+++ b/src/server/routes/api/auth/webauthn.ts
@@ -1,7 +1,7 @@
import { config } from '@/lib/config';
import { prisma } from '@/lib/db';
import { User, userSelect } from '@/lib/db/models/user';
-import { getSession } from '@/server/session';
+import { getSession, saveSession } from '@/server/session';
import { AuthenticationResponseJSON } from '@github/webauthn-json/dist/types/browser-ponyfill';
import fastifyPlugin from 'fastify-plugin';
@@ -47,8 +47,7 @@ export default fastifyPlugin(
});
if (!user) return res.badRequest('Invalid passkey');
- session.user = user;
- await session.save();
+ await saveSession(session, user);
delete (user as any).password;
diff --git a/src/server/routes/api/user/index.ts b/src/server/routes/api/user/index.ts
index 627e3c1f..e22c89c1 100755
--- a/src/server/routes/api/user/index.ts
+++ b/src/server/routes/api/user/index.ts
@@ -2,7 +2,7 @@ import { hashPassword } from '@/lib/crypto';
import { prisma } from '@/lib/db';
import { User, userSelect } from '@/lib/db/models/user';
import { userMiddleware } from '@/server/middleware/user';
-import { getSession } from '@/server/session';
+import { getSession, saveSession } from '@/server/session';
import fastifyPlugin from 'fastify-plugin';
export type ApiUserResponse = {
@@ -75,12 +75,13 @@ export default fastifyPlugin(
},
select: {
...userSelect,
+ password: true,
+ token: true,
},
});
const session = await getSession(req, res);
- session.user = user;
- await session.save();
+ await saveSession(session, user);
delete (user as any).password;
diff --git a/src/server/routes/api/user/token.ts b/src/server/routes/api/user/token.ts
index 2efde99d..9c9b2e6d 100755
--- a/src/server/routes/api/user/token.ts
+++ b/src/server/routes/api/user/token.ts
@@ -3,7 +3,6 @@ import { createToken, encryptToken } from '@/lib/crypto';
import { prisma } from '@/lib/db';
import { User, userSelect } from '@/lib/db/models/user';
import { userMiddleware } from '@/server/middleware/user';
-import { getSession } from '@/server/session';
import fastifyPlugin from 'fastify-plugin';
export type ApiUserTokenResponse = {
@@ -32,8 +31,6 @@ export default fastifyPlugin(
});
server.patch(PATH, { preHandler: [userMiddleware] }, async (req, res) => {
- const session = await getSession(req, res);
-
const user = await prisma.user.update({
where: {
id: req.user.id,
@@ -47,8 +44,6 @@ export default fastifyPlugin(
},
});
- session.user!.token = user.token;
-
delete (user as any).password;
return res.send({
diff --git a/src/server/session.ts b/src/server/session.ts
index 28abc1a3..3d6f1a6f 100644
--- a/src/server/session.ts
+++ b/src/server/session.ts
@@ -1,5 +1,7 @@
import { config } from '@/lib/config';
+import { prisma } from '@/lib/db';
import { User } from '@/lib/db/models/user';
+import { randomCharacters } from '@/lib/random';
import { FastifyReply, FastifyRequest } from 'fastify';
import { IncomingMessage, ServerResponse } from 'http';
import { getIronSession } from 'iron-session';
@@ -12,12 +14,17 @@ const cookieOptions = {
sameSite: 'lax',
};
+export type ZiplineSession = {
+ id: string | null;
+ sessionId: string | null;
+};
+
export async function getSession(
req: FastifyRequest | IncomingMessage,
reply: FastifyReply | ServerResponse,
) {
if (!(req as any).raw || !(req as any).raw) {
- const session = await getIronSession<{ user: User | null }>(
+ const session = await getIronSession(
req as IncomingMessage,
reply as ServerResponse,
{
@@ -30,7 +37,7 @@ export async function getSession(
return session;
}
- const session = await getIronSession<{ user: User | null }>(
+ const session = await getIronSession(
(req as FastifyRequest).raw,
(reply as FastifyReply).raw,
{
@@ -42,3 +49,25 @@ export async function getSession(
return session;
}
+
+export async function saveSession(
+ session: Awaited>,
+ user: User,
+ overwriteSessions = true,
+) {
+ session.id = user.id;
+
+ const sessionId = randomCharacters(32);
+ session.sessionId = sessionId;
+
+ await prisma.user.update({
+ where: {
+ id: user.id,
+ },
+ data: {
+ sessions: overwriteSessions ? { set: [sessionId] } : { push: sessionId },
+ },
+ });
+
+ await session.save();
+}