Skip to content

Commit

Permalink
feat: auth.refetch function
Browse files Browse the repository at this point in the history
  • Loading branch information
OrJDev committed Nov 13, 2024
1 parent e84cf4d commit 2295506
Show file tree
Hide file tree
Showing 9 changed files with 161 additions and 33 deletions.
5 changes: 5 additions & 0 deletions .changeset/twelve-stingrays-approve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@solid-mediakit/auth': patch
---

feat: auth.refetch function
2 changes: 1 addition & 1 deletion examples/auth/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { defineConfig } from '@solidjs/start/config'

export default defineConfig({
ssr: true,
middleware: './src/server/middleware.ts',
middleware: './src/middleware.ts',
vite: {
plugins: [
authVite({
Expand Down
1 change: 1 addition & 0 deletions examples/auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@solidjs/meta": "^0.29.4",
"@solidjs/router": "^0.15.1",
"@solidjs/start": "^1.0.8",
"solid-icons": "^1.1.0",
"solid-js": "^1.9.2",
"vinxi": "^0.4.3",
"zod": "^3.23.8"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { authMiddleware } from '@solid-mediakit/auth'
import { createMiddleware } from '@solidjs/start/middleware'
import { authOptions } from './auth'
import { authOptions } from './server/auth'

export default createMiddleware({
onRequest: [],
onRequest: [authMiddleware(true, authOptions)],
})
30 changes: 30 additions & 0 deletions examples/auth/src/routes/auth/[provider].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useAuth } from '@solid-mediakit/auth/client'
import { useParams } from '@solidjs/router'
import { createEffect, on, VoidComponent } from 'solid-js'

const AuthProvider: VoidComponent = () => {
const params = useParams()
const auth = useAuth()
createEffect(
on(auth.status, (status) => {
if (status === 'authenticated') {
window.close()
} else if (status === 'unauthenticated') {
void auth.signIn(params.provider)
}
}),
)

return (
<div class='h-full w-full flex items-center justify-center flex-col gap-4'>
<div class='text-white text-2xl font-bold animate-pulse'>
Redirecting...
</div>
<p class='text-offwhite text-lg font-medium'>
Please Wait While HackChat Is Validating Your Request
</p>
</div>
)
}

export default AuthProvider
67 changes: 67 additions & 0 deletions examples/auth/src/routes/auth/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import { Component, createEffect, VoidComponent } from 'solid-js'
import { AiFillGithub } from 'solid-icons/ai'
import { FaBrandsDiscord } from 'solid-icons/fa'
import { A } from '@solidjs/router'
import { capitalize } from '~/utils/string'
import { getSession, useAuth } from '@solid-mediakit/auth/client'
const Auth: VoidComponent = () => {
return (
<div class='flex flex-col gap-4 items-center h-full w-full'>
<h1 class='text-3xl font-bold text-offwhite'>
Log In To{' '}
<span class='decoration-offwhite underline decoration-dotted text-white'>
HackChat
</span>
</h1>
<div class='flex flex-col gap-3 w-[300px] items-center'>
<SignInMethod name='github' />
<SignInMethod name='discord' />
<div class='my-3 w-[80%] rounded-lg bg-gray-200 h-[0.5px]' />
<p class='text-gray-300 font-semibold text-sm w-full text-center'>
For privacy of the users, you are required to Sign In before sending
any messages.
</p>
</div>
</div>
)
}

export default Auth

const SignInMethod: Component<{ name: 'github' | 'discord' }> = (props) => {
const auth = useAuth()
return (
<button
style={{
'box-shadow': `0 0 0 1px ${
props.name === 'github' ? '#24292e' : '#5865F2'
}`,
}}
class={`flex gap-2 items-center w-full justify-center transition-all select-none ${
props.name === 'github'
? 'bg-[#24292e] hover:bg-[#555] hover:shadow-[#555]'
: 'hover:shadow-[#5865F2] bg-[#5865F2] hover:bg-opacity-80'
} text-white px-[14px] h-12 rounded-lg font-medium`}
onClick={() => {
const w = window.open(
`${window.location.origin}/auth/${props.name}`,
`Sign In With ${capitalize(props.name)}`,
)
setInterval(async () => {
console.log(
w?.closed,
auth.session(),
w?.closed && (await auth.refetch(true)),
)
}, 1000)
}}
>
{props.name === 'github' ? (
<AiFillGithub size={25} />
) : (
<FaBrandsDiscord size={25} />
)}
Continue With {capitalize(props.name)}
</button>
)
}
2 changes: 2 additions & 0 deletions examples/auth/src/utils/string.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export const capitalize = (str: string) =>
`${str.slice(0, 1).toUpperCase()}${str.slice(1)}`;
69 changes: 40 additions & 29 deletions packages/auth/solid/src/client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import {

export const SessionContext = createContext<{
sessionState: Accessor<SessionState>
refetchSessionState: () => unknown
refetchSessionState: (force?: boolean) => Promise<SessionState>
}>(undefined)

export interface SessionProviderProps {
Expand Down Expand Up @@ -106,6 +106,7 @@ export const useAuth = (): AuthRes => {
| 'unauthenticated'
| 'loading',
session: () => value.sessionState().data as Session | null | undefined,
refetch: async (force?: boolean) => await value.refetchSessionState(force),
}
}

Expand All @@ -124,7 +125,7 @@ export function SessionProvider(props: SessionProviderProps) {
? getSessionFromEvent(event! as unknown as AuthEvent)
: undefined

const _innerAction = async (): Promise<SessionState> => {
const authAction = async (): Promise<SessionState> => {
try {
const _session = await getSession(event)
if (_session) {
Expand All @@ -138,44 +139,53 @@ export function SessionProvider(props: SessionProviderProps) {
data: null,
}
} catch (e) {
console.error('@auth', e)
console.error('@solid-mediakit/auth error', e)
return {
status: 'unauthenticated',
data: null,
}
}
}

const authAction = async (initial?: boolean): Promise<SessionState> => {
if (initial && initialSession !== undefined && !props.refetchAfterServer) {
return getSessionState(initialSession)
}
return await _innerAction()
}
const [sessionState, { refetch: refetchSessionState }] =
createResource<SessionState>(
async (_, info) => {
const isForced =
typeof info.refetching === 'object'
? (info.refetching as { force?: boolean }).force
: false
const prev = info.value as SessionState

const [sessionState, { refetch: refetchSessionState }] = createResource(
async (_, info) => {
const prev = info.value as SessionState
if (isServer) {
if (initialSession !== undefined) {
if (isServer && initialSession !== undefined && !isForced) {
return getSessionState(initialSession)
}
}
return prev.status !== 'loading' ? prev : await authAction()
},
{
initialValue: initialSession
? getSessionState(initialSession)
: { status: 'loading', data: undefined },
deferStream: props.deferStream ?? true,
},
)

return !isForced && prev?.status !== 'loading'
? prev
: await authAction()
},
{
initialValue: initialSession
? getSessionState(initialSession)
: { status: 'loading', data: undefined },
deferStream: props.deferStream ?? true,
},
)

return (
<SessionContext.Provider
value={{
sessionState: sessionState as () => SessionState,
refetchSessionState,
refetchSessionState: async (force?: boolean) => {
const res = await refetchSessionState({ force: force ?? false })
if (res === null || res === undefined) {
return {
status: 'loading',
data: undefined,
}
}
return res
},
}}
>
{props.children}
Expand Down Expand Up @@ -208,6 +218,7 @@ type AuthRes = {
) => ReturnType<typeof signOut>
status: Accessor<'authenticated' | 'unauthenticated' | 'loading'>
session: Accessor<Session | null | undefined>
refetch: (force?: boolean) => Promise<SessionState>
}

export const getSession = async (
Expand Down Expand Up @@ -245,7 +256,7 @@ export const getSession = async (
async function signIn<
P extends RedirectableProviderType | undefined = undefined,
>(
refetchSessionState: () => unknown,
refetchSessionState: (force?: boolean) => unknown,
providerId?: LiteralUnion<
P extends RedirectableProviderType
? P | BuiltInProviderType
Expand Down Expand Up @@ -300,7 +311,7 @@ async function signIn<
const code = new URL(data.url).searchParams.get('code')

if (res.ok) {
await refetchSessionState()
await refetchSessionState(true)
}

return {
Expand All @@ -313,7 +324,7 @@ async function signIn<
}

async function signOut<R extends boolean = true>(
refetchSessionState: () => unknown,
refetchSessionState: (force?: boolean) => unknown,

options?: SignOutParams<R>,
) {
Expand Down Expand Up @@ -342,7 +353,7 @@ async function signOut<R extends boolean = true>(
return
}

await refetchSessionState()
await refetchSessionState(true)

return data
}
14 changes: 13 additions & 1 deletion pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 2295506

Please sign in to comment.