UNPKG

@convocomet/auth-astro

Version:

This is a fork of [Auth Astro](https://github.com/nowaythatworked/auth-astro), including many fixes and new features, which was created due to a lack of maintenance in the upstream version.

107 lines (93 loc) 3.36 kB
import type { LiteralUnion, SignInOptions, SignInAuthorizationParams, SignOutParams, } from 'next-auth/react' import type { BuiltInProviderType, RedirectableProviderType } from '@auth/core/providers' interface AstroSignInOptions extends SignInOptions { /** The base path for authentication (default: /api/auth) */ prefix?: string } interface AstroSignOutParams extends SignOutParams { /** The base path for authentication (default: /api/auth) */ prefix?: string } /** * Client-side method to initiate a signin flow * or send the user to the signin page listing all possible providers. * Automatically adds the CSRF token to the request. * * [Documentation](https://authjs.dev/reference/utilities/#signin) */ export async function signIn<P extends RedirectableProviderType | undefined = undefined>( providerId?: LiteralUnion< P extends RedirectableProviderType ? P | BuiltInProviderType : BuiltInProviderType >, options?: AstroSignInOptions, authorizationParams?: SignInAuthorizationParams ) { const { callbackUrl = window.location.href, redirect } = options ?? {} const { prefix = '/api/auth', ...opts } = options ?? {} // TODO: Support custom providers const isCredentials = providerId === 'credentials' const isEmail = providerId === 'email' const isSupportingReturn = isCredentials || isEmail // TODO: Handle custom base path const signInUrl = `${prefix}/${isCredentials ? 'callback' : 'signin'}/${providerId}` const _signInUrl = `${signInUrl}?${new URLSearchParams(authorizationParams)}` // TODO: Handle custom base path const csrfTokenResponse = await fetch(`${prefix}/csrf`) const { csrfToken } = await csrfTokenResponse.json() const res = await fetch(_signInUrl, { method: 'post', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Auth-Return-Redirect': '1', }, // @ts-expect-error -- ignore body: new URLSearchParams({ ...opts, csrfToken, callbackUrl, }), }) const data = await res.clone().json() const error = new URL(data.url).searchParams.get('error') if ((redirect ?? !isSupportingReturn) && !error) { // TODO: Do not redirect for Credentials and Email providers by default in next major window.location.href = data.url ?? callbackUrl // If url contains a hash, the browser does not reload the page. We reload manually if (data.url.includes('#')) window.location.reload() return } return res } /** * Signs the user out, by removing the session cookie. * Automatically adds the CSRF token to the request. * * [Documentation](https://authjs.dev/reference/utilities/#signout) */ export async function signOut(options?: AstroSignOutParams) { const { callbackUrl = window.location.href, prefix = '/api/auth' } = options ?? {} // TODO: Custom base path const csrfTokenResponse = await fetch(`${prefix}/csrf`) const { csrfToken } = await csrfTokenResponse.json() const res = await fetch(`${prefix}/signout`, { method: 'post', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Auth-Return-Redirect': '1', }, body: new URLSearchParams({ csrfToken, callbackUrl, }), }) const data = await res.json() const url = data.url ?? callbackUrl window.location.href = url // If url contains a hash, the browser does not reload the page. We reload manually if (url.includes('#')) window.location.reload() }