mirror of
https://github.com/diced/zipline.git
synced 2026-01-15 22:32:56 -08:00
fix: oauth state is encrypted
This commit is contained in:
@@ -11,7 +11,7 @@ export function findProvider(
|
||||
export const githubAuth = {
|
||||
url: (clientId: string, state?: string, redirectUri?: string) =>
|
||||
`https://github.com/login/oauth/authorize?client_id=${clientId}&scope=read:user${
|
||||
state ? `&state=${state}` : ''
|
||||
state ? `&state=${encodeURIComponent(state)}` : ''
|
||||
}${redirectUri ? `&redirect_uri=${encodeURIComponent(redirectUri)}` : ''}`,
|
||||
user: async (accessToken: string) => {
|
||||
const res = await fetch('https://api.github.com/user', {
|
||||
@@ -29,7 +29,7 @@ export const discordAuth = {
|
||||
url: (clientId: string, origin: string, state?: string, redirectUri?: string) =>
|
||||
`https://discord.com/api/oauth2/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(
|
||||
redirectUri ?? `${origin}/api/auth/oauth/discord`,
|
||||
)}&response_type=code&scope=identify${state ? `&state=${state}` : ''}`,
|
||||
)}&response_type=code&scope=identify${state ? `&state=${encodeURIComponent(state)}` : ''}`,
|
||||
user: async (accessToken: string) => {
|
||||
const res = await fetch('https://discord.com/api/users/@me', {
|
||||
headers: {
|
||||
@@ -47,7 +47,7 @@ export const googleAuth = {
|
||||
`https://accounts.google.com/o/oauth2/auth?client_id=${clientId}&redirect_uri=${encodeURIComponent(
|
||||
redirectUri ?? `${origin}/api/auth/oauth/google`,
|
||||
)}&response_type=code&access_type=offline&scope=https://www.googleapis.com/auth/userinfo.profile${
|
||||
state ? `&state=${state}` : ''
|
||||
state ? `&state=${encodeURIComponent(state)}` : ''
|
||||
}`,
|
||||
user: async (accessToken: string) => {
|
||||
const res = await fetch('https://www.googleapis.com/oauth2/v1/userinfo?alt=json', {
|
||||
@@ -65,7 +65,7 @@ export const oidcAuth = {
|
||||
url: (clientId: string, origin: string, authorizeUrl: string, state?: string, redirectUri?: string) =>
|
||||
`${authorizeUrl}?client_id=${clientId}&redirect_uri=${encodeURIComponent(
|
||||
redirectUri ?? `${origin}/api/auth/oauth/oidc`,
|
||||
)}&response_type=code&scope=openid+email+profile+offline_access${state ? `&state=${state}` : ''}`,
|
||||
)}&response_type=code&scope=openid+email+profile+offline_access${state ? `&state=${encodeURIComponent(state)}` : ''}`,
|
||||
user: async (accessToken: string, userInfoUrl: string) => {
|
||||
const res = await fetch(userInfoUrl, {
|
||||
headers: {
|
||||
|
||||
@@ -2,7 +2,7 @@ import { NextApiReq, NextApiRes } from '@/lib/response';
|
||||
import { OAuthProviderType } from '@prisma/client';
|
||||
import { prisma } from '../db';
|
||||
import { findProvider } from './providerUtil';
|
||||
import { createToken } from '../crypto';
|
||||
import { createToken, decrypt } from '../crypto';
|
||||
import { config } from '../config';
|
||||
import { User } from '../db/models/user';
|
||||
import Logger, { log } from '../logger';
|
||||
@@ -88,7 +88,14 @@ export const withOAuth =
|
||||
|
||||
const userOauth = findProvider(provider, user?.oauthProviders ?? []);
|
||||
|
||||
if (state === 'link') {
|
||||
let urlState;
|
||||
try {
|
||||
urlState = decrypt(decodeURIComponent(state ?? ''), config.core.secret);
|
||||
} catch {
|
||||
urlState = null;
|
||||
}
|
||||
|
||||
if (urlState === 'link') {
|
||||
if (!user) return res.unauthorized('invalid session');
|
||||
|
||||
if (findProvider(provider, user.oauthProviders))
|
||||
|
||||
@@ -6,8 +6,9 @@ import enabled from '@/lib/oauth/enabled';
|
||||
import { discordAuth } from '@/lib/oauth/providerUtil';
|
||||
import { fetchToDataURL } from '@/lib/base64';
|
||||
import Logger from '@/lib/logger';
|
||||
import { encrypt } from '@/lib/crypto';
|
||||
|
||||
async function handler({ code, state, host }: OAuthQuery, logger: Logger): Promise<OAuthResponse> {
|
||||
async function handler({ code, host }: OAuthQuery, logger: Logger): Promise<OAuthResponse> {
|
||||
if (!config.features.oauthRegistration)
|
||||
return {
|
||||
error: 'OAuth registration is disabled.',
|
||||
@@ -22,15 +23,18 @@ async function handler({ code, state, host }: OAuthQuery, logger: Logger): Promi
|
||||
error_code: 401,
|
||||
};
|
||||
|
||||
if (!code)
|
||||
if (!code) {
|
||||
const linkState = encrypt('link', config.core.secret);
|
||||
|
||||
return {
|
||||
redirect: discordAuth.url(
|
||||
config.oauth.discord.clientId!,
|
||||
`${config.core.returnHttpsUrls ? 'https' : 'http'}://${host}`,
|
||||
state,
|
||||
linkState,
|
||||
config.oauth.discord.redirectUri ?? undefined,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
const body = new URLSearchParams({
|
||||
client_id: config.oauth.discord.clientId!,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { fetchToDataURL } from '@/lib/base64';
|
||||
import { config } from '@/lib/config';
|
||||
import { encrypt } from '@/lib/crypto';
|
||||
import Logger from '@/lib/logger';
|
||||
import { combine } from '@/lib/middleware/combine';
|
||||
import { method } from '@/lib/middleware/method';
|
||||
@@ -7,7 +8,7 @@ import enabled from '@/lib/oauth/enabled';
|
||||
import { githubAuth } from '@/lib/oauth/providerUtil';
|
||||
import { OAuthQuery, OAuthResponse, withOAuth } from '@/lib/oauth/withOAuth';
|
||||
|
||||
async function handler({ code, state }: OAuthQuery, logger: Logger): Promise<OAuthResponse> {
|
||||
async function handler({ code }: OAuthQuery, logger: Logger): Promise<OAuthResponse> {
|
||||
if (!config.features.oauthRegistration)
|
||||
return {
|
||||
error: 'OAuth registration is disabled.',
|
||||
@@ -22,14 +23,17 @@ async function handler({ code, state }: OAuthQuery, logger: Logger): Promise<OAu
|
||||
error_code: 401,
|
||||
};
|
||||
|
||||
if (!code)
|
||||
if (!code) {
|
||||
const linkState = encrypt('link', config.core.secret);
|
||||
|
||||
return {
|
||||
redirect: githubAuth.url(
|
||||
config.oauth.github.clientId!,
|
||||
state,
|
||||
linkState,
|
||||
config.oauth.github.redirectUri ?? undefined,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
const body = JSON.stringify({
|
||||
client_id: config.oauth.github.clientId!,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { fetchToDataURL } from '@/lib/base64';
|
||||
import { config } from '@/lib/config';
|
||||
import { encrypt } from '@/lib/crypto';
|
||||
import Logger from '@/lib/logger';
|
||||
import { combine } from '@/lib/middleware/combine';
|
||||
import { method } from '@/lib/middleware/method';
|
||||
@@ -7,7 +8,7 @@ import enabled from '@/lib/oauth/enabled';
|
||||
import { googleAuth } from '@/lib/oauth/providerUtil';
|
||||
import { OAuthQuery, OAuthResponse, withOAuth } from '@/lib/oauth/withOAuth';
|
||||
|
||||
async function handler({ code, state, host }: OAuthQuery, _logger: Logger): Promise<OAuthResponse> {
|
||||
async function handler({ code, host }: OAuthQuery, _logger: Logger): Promise<OAuthResponse> {
|
||||
if (!config.features.oauthRegistration)
|
||||
return {
|
||||
error: 'OAuth registration is disabled.',
|
||||
@@ -22,15 +23,18 @@ async function handler({ code, state, host }: OAuthQuery, _logger: Logger): Prom
|
||||
error_code: 401,
|
||||
};
|
||||
|
||||
if (!code)
|
||||
if (!code) {
|
||||
const linkState = encrypt('link', config.core.secret);
|
||||
|
||||
return {
|
||||
redirect: googleAuth.url(
|
||||
config.oauth.google.clientId!,
|
||||
`${config.core.returnHttpsUrls ? 'https' : 'http'}://${host}`,
|
||||
state,
|
||||
linkState,
|
||||
config.oauth.google.redirectUri ?? undefined,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
const body = new URLSearchParams({
|
||||
client_id: config.oauth.google.clientId!,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { config } from '@/lib/config';
|
||||
import { encrypt } from '@/lib/crypto';
|
||||
import Logger from '@/lib/logger';
|
||||
import { combine } from '@/lib/middleware/combine';
|
||||
import { method } from '@/lib/middleware/method';
|
||||
@@ -7,7 +8,7 @@ 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
|
||||
async function handler({ code, state, host }: OAuthQuery, _logger: Logger): Promise<OAuthResponse> {
|
||||
async function handler({ code, host }: OAuthQuery, _logger: Logger): Promise<OAuthResponse> {
|
||||
if (!config.features.oauthRegistration)
|
||||
return {
|
||||
error: 'OAuth registration is disabled.',
|
||||
@@ -22,16 +23,19 @@ async function handler({ code, state, host }: OAuthQuery, _logger: Logger): Prom
|
||||
error_code: 401,
|
||||
};
|
||||
|
||||
if (!code)
|
||||
if (!code) {
|
||||
const linkState = encrypt('link', config.core.secret);
|
||||
|
||||
return {
|
||||
redirect: oidcAuth.url(
|
||||
config.oauth.oidc.clientId!,
|
||||
`${config.core.returnHttpsUrls ? 'https' : 'http'}://${host}`,
|
||||
config.oauth.oidc.authorizeUrl!,
|
||||
state,
|
||||
linkState,
|
||||
config.oauth.oidc.redirectUri ?? undefined,
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
const body = new URLSearchParams({
|
||||
client_id: config.oauth.oidc.clientId!,
|
||||
|
||||
Reference in New Issue
Block a user