Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion apps/blog-next/app/api/login/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { loginForm } from '@/lib/schemas/auth'

export async function POST(request: Request) {
const submission = await validate(request, loginForm, {
csrf: true,
throttle: 'login',
})

Expand Down
1 change: 0 additions & 1 deletion apps/blog-next/app/api/register/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { registerForm } from '@/lib/schemas/auth'

export async function POST(request: Request) {
const submission = await validate(request, registerForm, {
csrf: true,
throttle: 'register',
})

Expand Down
1 change: 0 additions & 1 deletion apps/blog-next/app/login/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { loginForm } from '@/lib/schemas/auth'

export async function loginAction(formData: FormData) {
const submission = await validate(formData, loginForm, {
csrf: true,
throttle: 'login',
})

Expand Down
1 change: 0 additions & 1 deletion apps/blog-next/app/login/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ const panelStyle = {

export default function LoginPage() {
const form = useForm(loginForm, {
csrf: true,
validateOn: 'blur',
initialValues: { email: '', password: '', remember: false },
async submitter({ formData }) {
Expand Down
1 change: 0 additions & 1 deletion apps/blog-next/app/register/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { registerForm } from '@/lib/schemas/auth'

export async function registerAction(formData: FormData) {
const submission = await validate(formData, registerForm, {
csrf: true,
throttle: 'register',
})

Expand Down
1 change: 0 additions & 1 deletion apps/blog-next/app/register/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ const panelStyle = {

export default function RegisterPage() {
const form = useForm(registerForm, {
csrf: true,
validateOn: 'blur',
initialValues: { name: '', email: '', password: '', passwordConfirmation: '' },
async submitter({ formData }) {
Expand Down
2 changes: 1 addition & 1 deletion apps/blog-next/config/security.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default defineSecurityConfig({
field: '_token',
header: 'X-CSRF-TOKEN',
cookie: 'XSRF-TOKEN',
except: [],
except: ['/api/v1/*'],
},
rateLimit: {
driver: 'file',
Expand Down
25 changes: 23 additions & 2 deletions apps/blog-next/proxy.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { authOnly, guestOnly, protectRoutes } from '@holo-js/auth/next/server'
import { csrfProtection } from '@holo-js/security/next/server'

export const proxy = protectRoutes(
const csrf = csrfProtection()
const auth = protectRoutes(
guestOnly({
routes: ['/login', '/register', '/forgot-password', '/reset-password'],
redirectTo: '/admin',
Expand All @@ -21,6 +23,25 @@ export const proxy = protectRoutes(
}),
)

export async function proxy(request: Parameters<typeof csrf>[0]) {
const csrfResponse = await csrf(request)
if (csrfResponse?.status === 419) {
return csrfResponse
}

const authResponse = await auth(request)
return authResponse ?? csrfResponse
}

export const config = {
matcher: ['/login', '/register', '/forgot-password', '/reset-password', '/admin/:path*', '/super-admin', '/super-admin/login'],
matcher: [
'/login',
'/register',
'/forgot-password',
'/reset-password',
'/admin/:path*',
'/super-admin',
'/super-admin/login',
'/api/:path*',
],
}
1 change: 0 additions & 1 deletion apps/blog-next/tests/login-page.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ describe('login action', () => {
})

expect(mocks.validate).toHaveBeenCalledWith(formData, {}, {
csrf: true,
throttle: 'login',
})
expect(mocks.login).toHaveBeenCalledWith({
Expand Down
3 changes: 0 additions & 3 deletions apps/blog-next/tests/register-page.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,9 @@ describe('register page', () => {
})

expect(mocks.useForm).toHaveBeenCalledWith(mocks.registerForm, expect.objectContaining({
csrf: true,
validateOn: 'blur',
}))
expect(mocks.validate).toHaveBeenCalledWith(expect.any(FormData), mocks.registerForm, {
csrf: true,
throttle: 'register',
})
expect(mocks.register).not.toHaveBeenCalled()
Expand Down Expand Up @@ -165,7 +163,6 @@ describe('registerAction', () => {

await expect(registerAction(new FormData())).resolves.toBe(failure)
expect(mocks.validate).toHaveBeenCalledWith(expect.any(FormData), mocks.registerForm, {
csrf: true,
throttle: 'register',
})
expect(mocks.register).not.toHaveBeenCalled()
Expand Down
1 change: 0 additions & 1 deletion apps/blog-nuxt/app/pages/login/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { loginForm } from '#shared/schemas/auth'

const { refreshUser } = await useAuth()
const form = useForm(loginForm, {
csrf: true,
validateOn: 'blur',
initialValues: { email: '', password: '', remember: false },
async submitter({ formData }) {
Expand Down
1 change: 0 additions & 1 deletion apps/blog-nuxt/app/pages/register/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { registerForm } from '#shared/schemas/auth'

const { refreshUser } = await useAuth()
const form = useForm(registerForm, {
csrf: true,
validateOn: 'blur',
initialValues: { name: '', email: '', password: '', passwordConfirmation: '' },
async submitter({ formData }) {
Expand Down
2 changes: 1 addition & 1 deletion apps/blog-nuxt/config/security.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default defineSecurityConfig({
field: '_token',
header: 'X-CSRF-TOKEN',
cookie: 'XSRF-TOKEN',
except: [],
except: ['/api/v1/*'],
},
rateLimit: {
driver: 'file',
Expand Down
1 change: 0 additions & 1 deletion apps/blog-nuxt/server/api/login.post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { loginForm } from '#shared/schemas/auth'

export default defineEventHandler(async (event) => {
const submission = await validate(event, loginForm, {
csrf: true,
throttle: 'login',
})

Expand Down
1 change: 0 additions & 1 deletion apps/blog-nuxt/server/api/register.post.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { registerForm } from '#shared/schemas/auth'

export default defineEventHandler(async (event) => {
const submission = await validate(event, registerForm, {
csrf: true,
throttle: 'register',
})

Expand Down
3 changes: 3 additions & 0 deletions apps/blog-nuxt/server/middleware/csrf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { csrfProtection } from '@holo-js/security/nuxt/server'

export default csrfProtection()
2 changes: 1 addition & 1 deletion apps/blog-sveltekit/config/security.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default defineSecurityConfig({
field: '_token',
header: 'X-CSRF-TOKEN',
cookie: 'XSRF-TOKEN',
except: [],
except: ['/api/v1/*'],
},
rateLimit: {
driver: 'file',
Expand Down
2 changes: 2 additions & 0 deletions apps/blog-sveltekit/src/hooks.server.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { sequence } from '@sveltejs/kit/hooks'
import { authOnly, guestOnly } from '@holo-js/auth/sveltekit/server'
import { csrfProtection } from '@holo-js/security/sveltekit/server'

export const handle = sequence(
csrfProtection(),
guestOnly({
routes: ['/login', '/register', '/forgot-password', '/reset-password'],
redirectTo: '/admin',
Expand Down
4 changes: 1 addition & 3 deletions apps/blog-sveltekit/src/routes/+layout.server.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
import { auth } from '@holo-js/auth/sveltekit/server'
import { csrf } from '@holo-js/security'
import type { LayoutServerLoad } from './$types'

export const load = (async ({ request }) => {
export const load = (async () => {
const currentAuth = await auth()

return {
auth: currentAuth,
csrf: await csrf.field(request),
}
}) satisfies LayoutServerLoad
10 changes: 8 additions & 2 deletions apps/blog-sveltekit/src/routes/login/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { fail, redirect } from '@sveltejs/kit'
import { login } from '@holo-js/auth'
import { validate } from '@holo-js/forms'
import { csrf } from '@holo-js/security'

import { loginForm } from '$lib/schemas/auth'
import type { Actions } from './$types'
import type { Actions, PageServerLoad } from './$types'

export const load = (async ({ request }) => ({
csrf: {
input: await csrf.input(request),
},
})) satisfies PageServerLoad

export const actions = {
default: async ({ request }) => {
const submission = await validate(request, loginForm, {
csrf: true,
throttle: 'login',
})

Expand Down
2 changes: 1 addition & 1 deletion apps/blog-sveltekit/src/routes/login/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
</div>

<form class="stack" method="post">
<input type="hidden" name={data.csrf.name} value={data.csrf.value} />
<input {...data.csrf.input} />

{#if formError}
<p class="error">{formError}</p>
Expand Down
10 changes: 8 additions & 2 deletions apps/blog-sveltekit/src/routes/register/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { fail, redirect } from '@sveltejs/kit'
import { loginUsing, register } from '@holo-js/auth'
import { validate } from '@holo-js/forms'
import { csrf } from '@holo-js/security'

import { registerForm } from '$lib/schemas/auth'
import type { Actions } from './$types'
import type { Actions, PageServerLoad } from './$types'

export const load = (async ({ request }) => ({
csrf: {
input: await csrf.input(request),
},
})) satisfies PageServerLoad

export const actions = {
default: async ({ request }) => {
const submission = await validate(request, registerForm, {
csrf: true,
throttle: 'register',
})

Expand Down
2 changes: 1 addition & 1 deletion apps/blog-sveltekit/src/routes/register/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
</div>

<form class="stack" method="post">
<input type="hidden" name={data.csrf.name} value={data.csrf.value} />
<input {...data.csrf.input} />

{#if formError}
<p class="error">{formError}</p>
Expand Down
10 changes: 8 additions & 2 deletions apps/blog-sveltekit/src/routes/super-admin/login/+page.server.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
import { fail, redirect } from '@sveltejs/kit'
import auth from '@holo-js/auth'
import { validate } from '@holo-js/forms'
import { csrf } from '@holo-js/security'

import { loginForm } from '$lib/schemas/auth'
import type { Actions } from './$types'
import type { Actions, PageServerLoad } from './$types'

export const load = (async ({ request }) => ({
csrf: {
input: await csrf.input(request),
},
})) satisfies PageServerLoad

export const actions = {
default: async ({ request }) => {
const submission = await validate(request, loginForm, {
csrf: true,
throttle: 'login',
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
</div>

<form class="stack" method="post">
<input type="hidden" name={data.csrf.name} value={data.csrf.value} />
<input {...data.csrf.input} />

{#if formError}
<p class="error">{formError}</p>
Expand Down
3 changes: 0 additions & 3 deletions apps/blog-sveltekit/tests/auth-page-actions.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ describe('SvelteKit login page action', () => {
expect(response.status).toBe(422)
expect(response).toEqual(failure)
expect(mocks.validate).toHaveBeenCalledWith(expect.any(Request), mocks.loginForm, {
csrf: true,
throttle: 'login',
})
expect(mocks.login).not.toHaveBeenCalled()
Expand Down Expand Up @@ -165,7 +164,6 @@ describe('SvelteKit register page action', () => {
expect(response.status).toBe(422)
expect(response).toEqual(failure)
expect(mocks.validate).toHaveBeenCalledWith(expect.any(Request), mocks.registerForm, {
csrf: true,
throttle: 'register',
})
expect(mocks.register).not.toHaveBeenCalled()
Expand Down Expand Up @@ -278,7 +276,6 @@ describe('SvelteKit super admin login page action', () => {
expect(response.status).toBe(422)
expect(response).toEqual(failure)
expect(mocks.validate).toHaveBeenCalledWith(expect.any(Request), mocks.loginForm, {
csrf: true,
throttle: 'login',
})
expect(mocks.guardLogin).not.toHaveBeenCalled()
Expand Down
4 changes: 0 additions & 4 deletions apps/docs/docs/auth/current-auth-client.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ import { loginForm } from '@/lib/schemas/login'

export async function loginAction(formData: FormData) {
const submission = await validate(formData, loginForm, {
csrf: true,
throttle: 'login',
})

Expand All @@ -86,7 +85,6 @@ import { loginAction } from './actions'

export default function LoginPage() {
const form = useForm(loginForm, {
csrf: true,
async submitter({ formData }) {
return await loginAction(formData)
},
Expand Down Expand Up @@ -131,7 +129,6 @@ import { loginForm } from '$lib/schemas/login'

export async function POST({ request }: { request: Request }) {
const submission = await validate(request, loginForm, {
csrf: true,
throttle: 'login',
})

Expand Down Expand Up @@ -161,7 +158,6 @@ export async function POST({ request }: { request: Request }) {

const auth = useAuth()
const form = useForm(loginForm, {
csrf: true,
async submitter({ formData }) {
const submission = await (await fetch('/api/login', { method: 'POST', body: formData })).json()
if (submission.ok === true && typeof submission.data?.redirectTo === 'string') {
Expand Down
Loading