Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e0136bd
added enhancment to allow signUp function return response if SignUpOp…
iamKiNG-Fr Aug 24, 2024
7a4ed34
Merge branch 'main' into enh/843-signup-flow-enhancement
iamKiNG-Fr Sep 8, 2024
e3bf0fc
sign up function to return data, test written
iamKiNG-Fr Sep 8, 2024
1bdf144
Discard changes to pnpm-lock.yaml
zoey-kaiser Sep 12, 2024
d9951f6
fix: oxlint issue
zoey-kaiser Sep 12, 2024
5477cde
Merge branch 'main' into enh/843-signup-flow-enhancement
iamKiNG-Fr Sep 17, 2024
0caeefc
enh: added generic type support to signUp function for flexible retur…
iamKiNG-Fr Sep 17, 2024
a76b601
Merge branch 'enh/843-signup-flow-enhancement' of https://github.com/…
iamKiNG-Fr Sep 17, 2024
9cff966
Resolved lint errors and formatting issues
iamKiNG-Fr Sep 17, 2024
e5373a4
Merge branch 'main' into enh/843-signup-flow-enhancement
zoey-kaiser Sep 18, 2024
6ee85a0
Merge branch 'main' into enh/843-signup-flow-enhancement
iamKiNG-Fr Sep 19, 2024
b25597b
Update src/runtime/composables/local/useAuth.ts
iamKiNG-Fr Sep 19, 2024
86fd25a
Update playground-local/pages/register.vue by aligning test-ids
iamKiNG-Fr Sep 19, 2024
94cd4a3
Update playground-local/pages/register.vue to remove unused test-id r…
iamKiNG-Fr Sep 19, 2024
f11f9c4
Update playground-local/tests/local.spec.ts by unifying updated test-ids
iamKiNG-Fr Sep 19, 2024
98e33a9
Update src/runtime/composables/local/useAuth.ts
iamKiNG-Fr Sep 19, 2024
75ed74a
Merge branch 'main' into enh/843-signup-flow-enhancement
phoenix-ru Apr 10, 2025
8fd0e24
fix: fix a type in `signUp` function
phoenix-ru Apr 10, 2025
f9ac88f
refact: make demo implementation more unified
phoenix-ru Apr 10, 2025
916956f
test: fix E2E tests
phoenix-ru Apr 10, 2025
653f80c
chore: remove unused imports
phoenix-ru Apr 10, 2025
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
3 changes: 2 additions & 1 deletion playground-local/nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ export default defineNuxtConfig({
provider: {
type: 'local',
endpoints: {
getSession: { path: '/user' }
getSession: { path: '/user' },
signUp: { path: '/signup', method: 'post' }
},
pages: {
login: '/'
Expand Down
4 changes: 4 additions & 0 deletions playground-local/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ definePageMeta({ auth: false })
-> manual login, logout, refresh button
</nuxt-link>
<br>
<nuxt-link to="/register">
-> Click to signup
</nuxt-link>
<br>
<nuxt-link to="/protected/globally">
-> globally protected page
</nuxt-link>
Expand Down
45 changes: 45 additions & 0 deletions playground-local/pages/register.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<script setup>
import { ref } from 'vue'
import { definePageMeta, useAuth } from '#imports'
const { signUp } = useAuth()
const username = ref('')
const password = ref('')
const response = ref()
async function register() {
try {
const signUpResponse = await signUp({ username: username.value, password: password.value }, undefined, { preventLoginFlow: true })
response.value = signUpResponse
}
catch (error) {
response.value = { error: 'Failed to sign up' }
console.error(error)
}
}
definePageMeta({
auth: {
unauthenticatedOnly: true,
navigateAuthenticatedTo: '/',
},
})
</script>

<template>
<div>
<form @submit.prevent="register">
<p><i>*password should have at least 6 characters</i></p>
<input v-model="username" type="text" placeholder="Username" data-testid="regUsername">
<input v-model="password" type="password" placeholder="Password" data-testid="regPassword">
<button type="submit" data-testid="regSubmit">
sign up
</button>
</form>
<div v-if="response">
<h2>Response</h2>
<pre data-testid="regResponse">{{ response }}</pre>
</div>
</div>
</template>
40 changes: 40 additions & 0 deletions playground-local/server/api/auth/signup.post.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { createError, eventHandler, readBody } from 'h3'
import { z } from 'zod'
import { sign } from 'jsonwebtoken'

export const SECRET = 'dummy'

export default eventHandler(async (event) => {
// Define the schema for validating the incoming data
const result = z.object({
username: z.string(),
password: z.string().min(6)
}).safeParse(await readBody(event))

// If validation fails, return an error
if (!result.success) {
throw createError({
statusCode: 400,
statusMessage: 'Invalid input, please provide a valid email and a password of at least 6 characters.'
})
}

const { username } = result.data

const expiresIn = '1h' // token expiry (1 hour)
const user = { username } // Payload for the token, includes the email

// Sign the JWT with the user payload and secret
const accessToken = sign(user, SECRET, { expiresIn })

// Return a success response with the email and the token
return {
message: 'Signup successful!',
user: {
username
},
token: {
accessToken
}
}
})
26 changes: 26 additions & 0 deletions playground-local/tests/local.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,4 +59,30 @@ describe('local Provider', async () => {
await signoutButton.click()
await playwrightExpect(status).toHaveText(STATUS_UNAUTHENTICATED)
})

it('should sign up and return signup data when preventLoginFlow: true', async () => {
const page = await createPage('/register') // Navigate to signup page

const [
usernameInput,
passwordInput,
submitButton,
] = await Promise.all([
page.getByTestId('regUsername'),
page.getByTestId('regPassword'),
page.getByTestId('regSubmit')
])

await usernameInput.fill('newuser')
await passwordInput.fill('hunter2')

// Click button and wait for API to finish
const responsePromise = page.waitForResponse(/\/api\/auth\/signup/)
await submitButton.click()
const response = await responsePromise

// Expect the response to return signup data
const responseBody = await response.json() // Parse response
playwrightExpect(responseBody).toBeDefined() // Ensure data is returned
})
})
10 changes: 6 additions & 4 deletions src/runtime/composables/local/useAuth.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { type Ref, readonly } from 'vue'

import type { CommonUseAuthReturn, GetSessionOptions, SecondarySignInOptions, SignInFunc, SignOutFunc, SignUpOptions } from '../../types'
import { jsonPointerGet, objectFromJsonPointer, useTypedBackendConfig } from '../../helpers'
import { _fetch } from '../../utils/fetch'
Expand Down Expand Up @@ -160,17 +159,20 @@ async function getSession(getSessionOptions?: GetSessionOptions): Promise<Sessio
return data.value
}

async function signUp(credentials: Credentials, signInOptions?: SecondarySignInOptions, signUpOptions?: SignUpOptions) {
async function signUp<T>(credentials: Credentials, signInOptions?: SecondarySignInOptions, signUpOptions?: SignUpOptions): Promise<T> {
const nuxt = useNuxtApp()

const { path, method } = useTypedBackendConfig(useRuntimeConfig(), 'local').endpoints.signUp
await _fetch(nuxt, path, {

// Holds result from fetch to be returned if signUpOptions?.preventLoginFlow is true
const result = await _fetch<T>(nuxt, path, {
method,
body: credentials
})

if (signUpOptions?.preventLoginFlow) {
return
// Returns result
return result
}

return signIn(credentials, signInOptions)
Expand Down