Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
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
6 changes: 3 additions & 3 deletions app/components/Header/AuthModal.client.vue
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
<script setup lang="ts">
const handleInput = shallowRef('')

const route = useRoute()
const { user, logout } = useAtproto()

async function handleBlueskySignIn() {
await navigateTo(
{
path: '/api/auth/atproto',
query: { handle: 'https://bsky.social' },
query: { handle: 'https://bsky.social', returnTo: route.fullPath },
},
{ external: true },
)
Expand All @@ -17,7 +17,7 @@ async function handleCreateAccount() {
await navigateTo(
{
path: '/api/auth/atproto',
query: { handle: 'https://npmx.social', create: 'true' },
query: { handle: 'https://npmx.social', create: 'true', returnTo: route.fullPath },
},
{ external: true },
)
Expand Down
17 changes: 16 additions & 1 deletion server/api/auth/atproto.get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,18 @@ export default defineEventHandler(async event => {
}

const query = getQuery(event)
const rawReturnTo = query.returnTo?.toString() || '/'
// Validate returnTo is a safe relative path (prevent open redirect)
const isRelativePath = rawReturnTo.startsWith('/') && !rawReturnTo.startsWith('//') && !rawReturnTo.includes(':')
Comment thread
danielroe marked this conversation as resolved.
Outdated
const returnTo = isRelativePath ? rawReturnTo : '/'

setCookie(event, 'auth_return_to', returnTo, {
maxAge: 60 * 5,
httpOnly: true,
// secure only if NOT in dev mode
secure: !import.meta.dev,
})

const clientMetadata = getOauthClientMetadata()
const { stateStore, sessionStore } = useOAuthStorage(event)

Expand Down Expand Up @@ -60,5 +72,8 @@ export default defineEventHandler(async event => {

await session.update(miniDoc)

return sendRedirect(event, '/')
const returnToURL = getCookie(event, 'auth_return_to') || '/'
deleteCookie(event, 'auth_return_to')

return sendRedirect(event, returnToURL)
})
Loading