kopia lustrzana https://github.com/cloudflare/wildebeest
add access check to isUserAdmin function
rodzic
db7f1bf13a
commit
d505ed278e
|
@ -2,8 +2,9 @@ import { component$, useStore, useSignal, $ } from '@builder.io/qwik'
|
|||
import { loader$ } from '@builder.io/qwik-city'
|
||||
import { checkAuth } from '~/utils/checkAuth'
|
||||
|
||||
export const loader = loader$(async ({ request, platform, redirect }) => {
|
||||
const isAuthorized = await checkAuth(request, platform)
|
||||
export const loader = loader$(async ({ cookie, request, platform, redirect }) => {
|
||||
const jwt = cookie.get('CF_Authorization')?.value ?? ''
|
||||
const isAuthorized = await checkAuth(request, jwt, platform.ACCESS_AUTH_DOMAIN, platform.ACCESS_AUD)
|
||||
|
||||
if (!isAuthorized) {
|
||||
redirect(303, '/explore')
|
||||
|
|
|
@ -1,14 +1,16 @@
|
|||
import { component$, Slot } from '@builder.io/qwik'
|
||||
import { loader$ } from '@builder.io/qwik-city'
|
||||
import { parse } from 'cookie'
|
||||
import { getDatabase } from 'wildebeest/backend/src/database'
|
||||
import { WildebeestLogo } from '~/components/MastodonLogo'
|
||||
import { getErrorHtml } from '~/utils/getErrorHtml/getErrorHtml'
|
||||
import { isUserAdmin } from '~/utils/isUserAdmin'
|
||||
|
||||
export const authLoader = loader$(async ({ cookie, platform, html }) => {
|
||||
export const authLoader = loader$(async ({ request, platform, html }) => {
|
||||
const database = await getDatabase(platform)
|
||||
const jwt = cookie.get('CF_Authorization')?.value ?? ''
|
||||
const isAdmin = await isUserAdmin(jwt, database)
|
||||
const cookie = parse(request.headers.get('Cookie') || '')
|
||||
const jwtCookie = cookie.CF_Authorization ?? ''
|
||||
const isAdmin = await isUserAdmin(request, jwtCookie, platform.ACCESS_AUTH_DOMAIN, platform.ACCESS_AUD, database)
|
||||
|
||||
if (!isAdmin) {
|
||||
return html(401, getErrorHtml("You're unauthorized to view this page"))
|
||||
|
|
|
@ -1,17 +1,4 @@
|
|||
import { component$ } from '@builder.io/qwik'
|
||||
import { loader$ } from '@builder.io/qwik-city'
|
||||
// import { checkAuth } from '~/utils/checkAuth'
|
||||
|
||||
export const loader = loader$(async ({ redirect }) => {
|
||||
// Hiding this page for now
|
||||
redirect(303, '/explore')
|
||||
|
||||
// const isAuthorized = await checkAuth(request, platform)
|
||||
|
||||
// if (!isAuthorized) {
|
||||
// redirect(303, '/explore')
|
||||
// }
|
||||
})
|
||||
|
||||
export default component$(() => {
|
||||
return (
|
||||
|
|
|
@ -8,8 +8,9 @@ type AccessLoaderData = {
|
|||
isAuthorized: boolean
|
||||
}
|
||||
|
||||
export const accessLoader = loader$<Promise<AccessLoaderData>>(async ({ platform, request }) => {
|
||||
const isAuthorized = await checkAuth(request, platform)
|
||||
export const accessLoader = loader$<Promise<AccessLoaderData>>(async ({ platform, request, cookie }) => {
|
||||
const jwt = cookie.get('CF_Authorization')?.value ?? ''
|
||||
const isAuthorized = await checkAuth(request, jwt, platform.ACCESS_AUTH_DOMAIN, platform.ACCESS_AUD)
|
||||
|
||||
return {
|
||||
isAuthorized,
|
||||
|
|
|
@ -1,27 +1,20 @@
|
|||
import { RequestContext } from '@builder.io/qwik-city/middleware/request-handler'
|
||||
import * as access from 'wildebeest/backend/src/access'
|
||||
|
||||
type Env = {
|
||||
ACCESS_AUTH_DOMAIN: string
|
||||
ACCESS_AUD: string
|
||||
}
|
||||
|
||||
export const checkAuth = async (request: RequestContext, platform: Env) => {
|
||||
const jwt = request.headers.get('Cf-Access-Jwt-Assertion') || ''
|
||||
export const checkAuth = async (request: Request, jwt: string, accessAuthDomain: string, accessAud: string) => {
|
||||
if (!jwt) return false
|
||||
|
||||
try {
|
||||
const validate = access.generateValidator({
|
||||
jwt,
|
||||
domain: platform.ACCESS_AUTH_DOMAIN,
|
||||
aud: platform.ACCESS_AUD,
|
||||
domain: accessAuthDomain,
|
||||
aud: accessAud,
|
||||
})
|
||||
await validate(new Request(request.url))
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
|
||||
const identity = await access.getIdentity({ jwt, domain: platform.ACCESS_AUTH_DOMAIN })
|
||||
const identity = await access.getIdentity({ jwt, domain: accessAuthDomain })
|
||||
if (identity) {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -1,12 +1,25 @@
|
|||
import { emailSymbol } from 'wildebeest/backend/src/activitypub/actors'
|
||||
import { Database } from 'wildebeest/backend/src/database'
|
||||
import { getAdmins } from 'wildebeest/functions/api/wb/settings/server/admins'
|
||||
import { checkAuth } from './checkAuth'
|
||||
import { getJwtEmail } from './getJwtEmail'
|
||||
|
||||
export async function isUserAdmin(jwtCookie: string, database: Database): Promise<boolean> {
|
||||
export async function isUserAdmin(
|
||||
request: Request,
|
||||
jwt: string,
|
||||
accessAuthDomain: string,
|
||||
accessAud: string,
|
||||
database: Database
|
||||
): Promise<boolean> {
|
||||
let email: string
|
||||
|
||||
try {
|
||||
email = getJwtEmail(jwtCookie)
|
||||
const authenticated = await checkAuth(request, jwt, accessAuthDomain, accessAud)
|
||||
if (!authenticated) {
|
||||
return false
|
||||
}
|
||||
|
||||
email = getJwtEmail(jwt)
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -2,11 +2,11 @@ import type { Env } from 'wildebeest/backend/src/types/env'
|
|||
import type { ContextData } from 'wildebeest/backend/src/types/context'
|
||||
import * as errors from 'wildebeest/backend/src/errors'
|
||||
import { type Database, getDatabase } from 'wildebeest/backend/src/database'
|
||||
import { parse } from 'cookie'
|
||||
import { isUserAdmin } from 'wildebeest/frontend/src/utils/isUserAdmin'
|
||||
import { parse } from 'cookie'
|
||||
|
||||
export const onRequestGet: PagesFunction<Env, any, ContextData> = async ({ env, request }) => {
|
||||
return handleRequestPost(await getDatabase(env), request)
|
||||
return handleRequestPost(await getDatabase(env), request, env.ACCESS_AUTH_DOMAIN, env.ACCESS_AUD)
|
||||
}
|
||||
|
||||
export async function handleRequestGet(db: Database) {
|
||||
|
@ -21,13 +21,13 @@ export async function handleRequestGet(db: Database) {
|
|||
}
|
||||
|
||||
export const onRequestPost: PagesFunction<Env, any, ContextData> = async ({ env, request }) => {
|
||||
return handleRequestPost(await getDatabase(env), request)
|
||||
return handleRequestPost(await getDatabase(env), request, env.ACCESS_AUTH_DOMAIN, env.ACCESS_AUD)
|
||||
}
|
||||
|
||||
export async function handleRequestPost(db: Database, request: Request) {
|
||||
export async function handleRequestPost(db: Database, request: Request, accessAuthDomain: string, accessAud: string) {
|
||||
const cookie = parse(request.headers.get('Cookie') || '')
|
||||
const jwt = cookie['CF_Authorization']
|
||||
const isAdmin = await isUserAdmin(jwt, db)
|
||||
const isAdmin = await isUserAdmin(request, jwt, accessAuthDomain, accessAud, db)
|
||||
|
||||
if (!isAdmin) {
|
||||
return errors.notAuthorized('Lacking authorization rights to edit server rules')
|
||||
|
@ -56,10 +56,10 @@ export async function upsertRule(db: Database, rule: { id?: number; text: string
|
|||
.run()
|
||||
}
|
||||
|
||||
export async function handleRequestDelete(db: Database, request: Request) {
|
||||
export async function handleRequestDelete(db: Database, request: Request, accessAuthDomain: string, accessAud: string) {
|
||||
const cookie = parse(request.headers.get('Cookie') || '')
|
||||
const jwt = cookie['CF_Authorization']
|
||||
const isAdmin = await isUserAdmin(jwt, db)
|
||||
const isAdmin = await isUserAdmin(request, jwt, accessAuthDomain, accessAud, db)
|
||||
|
||||
if (!isAdmin) {
|
||||
return errors.notAuthorized('Lacking authorization rights to edit server rules')
|
||||
|
|
|
@ -7,7 +7,7 @@ import { isUserAdmin } from 'wildebeest/frontend/src/utils/isUserAdmin'
|
|||
import { ServerSettingsData } from 'wildebeest/frontend/src/routes/(admin)/settings/server-settings/layout'
|
||||
|
||||
export const onRequestGet: PagesFunction<Env, any, ContextData> = async ({ env, request }) => {
|
||||
return handleRequestPost(await getDatabase(env), request)
|
||||
return handleRequestPost(await getDatabase(env), request, env.ACCESS_AUTH_DOMAIN, env.ACCESS_AUD)
|
||||
}
|
||||
|
||||
export async function handleRequestGet(db: Database) {
|
||||
|
@ -30,13 +30,13 @@ export async function handleRequestGet(db: Database) {
|
|||
}
|
||||
|
||||
export const onRequestPost: PagesFunction<Env, any, ContextData> = async ({ env, request }) => {
|
||||
return handleRequestPost(await getDatabase(env), request)
|
||||
return handleRequestPost(await getDatabase(env), request, env.ACCESS_AUTH_DOMAIN, env.ACCESS_AUD)
|
||||
}
|
||||
|
||||
export async function handleRequestPost(db: Database, request: Request) {
|
||||
export async function handleRequestPost(db: Database, request: Request, accessAuthDomain: string, accessAud: string) {
|
||||
const cookie = parse(request.headers.get('Cookie') || '')
|
||||
const jwt = cookie['CF_Authorization']
|
||||
const isAdmin = await isUserAdmin(jwt, db)
|
||||
const isAdmin = await isUserAdmin(request, jwt, accessAuthDomain, accessAud, db)
|
||||
|
||||
if (!isAdmin) {
|
||||
return errors.notAuthorized('Lacking authorization rights to edit server settings')
|
||||
|
|
|
@ -8,6 +8,7 @@ import { getClientById } from 'wildebeest/backend/src/mastodon/client'
|
|||
import * as access from 'wildebeest/backend/src/access'
|
||||
import { getPersonByEmail } from 'wildebeest/backend/src/activitypub/actors'
|
||||
import { type Database, getDatabase } from 'wildebeest/backend/src/database'
|
||||
import { checkAuth } from 'wildebeest/frontend/src/utils/checkAuth'
|
||||
|
||||
// Extract the JWT token sent by Access (running before us).
|
||||
const extractJWTFromRequest = (request: Request) => request.headers.get('Cf-Access-Jwt-Assertion') || ''
|
||||
|
@ -79,18 +80,14 @@ export async function handleRequestPost(
|
|||
}
|
||||
|
||||
const jwt = extractJWTFromRequest(request)
|
||||
if (!jwt) {
|
||||
const isAuthenticated = await checkAuth(request, jwt, accessDomain, accessAud)
|
||||
|
||||
if (!isAuthenticated) {
|
||||
return new Response('', { status: 401 })
|
||||
}
|
||||
const validate = access.generateValidator({ jwt, domain: accessDomain, aud: accessAud })
|
||||
await validate(request)
|
||||
|
||||
const identity = await access.getIdentity({ jwt, domain: accessDomain })
|
||||
if (!identity) {
|
||||
return new Response('', { status: 401 })
|
||||
}
|
||||
|
||||
const isFirstLogin = (await getPersonByEmail(db, identity.email)) === null
|
||||
const isFirstLogin = (await getPersonByEmail(db, identity!.email)) === null
|
||||
|
||||
return buildRedirect(db, request, isFirstLogin, jwt)
|
||||
}
|
||||
|
|
Ładowanie…
Reference in New Issue