Skip to content

Commit 3d4fa56

Browse files
chore: wip
1 parent afefcbb commit 3d4fa56

File tree

13 files changed

+94
-109
lines changed

13 files changed

+94
-109
lines changed

app/Listener.ts

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,27 @@ import { listen } from '@stacksjs/events'
22
import { path as p } from '@stacksjs/path'
33
import events from './Events'
44

5-
for (const key in events) {
6-
if (Object.hasOwn(events, key)) {
7-
const eventKey = key
8-
const eventListeners = events[key]
5+
export async function handleEvents() {
6+
for (const key in events) {
7+
if (Object.hasOwn(events, key)) {
8+
const eventKey = key
9+
const eventListeners = events[key]
910

10-
for (const eventListener of eventListeners) {
11-
const modulePath = eventListener
11+
for (const eventListener of eventListeners) {
12+
const modulePath = eventListener
1213

13-
if (isFunction(modulePath)) {
14-
await modulePath()
15-
}
16-
else {
17-
try {
18-
const actionModule = await import(p.projectPath(`Actions/${modulePath}.ts`))
19-
20-
listen(eventKey, e => actionModule.default.handle(e))
14+
if (isFunction(modulePath)) {
15+
await modulePath()
2116
}
22-
catch (error) {
23-
handleError(`Module not found: ${modulePath}`, error)
17+
else {
18+
try {
19+
const actionModule = await import(p.projectPath(`Actions/${modulePath}.ts`))
20+
21+
listen(eventKey, e => actionModule.default.handle(e))
22+
}
23+
catch (error) {
24+
handleError(`Module not found: ${modulePath}`, error)
25+
}
2426
}
2527
}
2628
}

app/Middleware/Api.ts

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Middleware, request } from '@stacksjs/router'
2+
import { HttpError } from 'index'
23
import { AccessToken, Team } from '../../storage/framework/orm/src'
34

45
export default new Middleware({
@@ -7,42 +8,36 @@ export default new Middleware({
78
async handle() {
89
const bearerToken = request.bearerToken() || ''
910

10-
if (!bearerToken) {
11-
throw { message: 'Unauthorized.', status: 401 }
12-
}
11+
if (!bearerToken)
12+
throw new HttpError(401, 'Unauthorized.')
1313

1414
const parts = bearerToken.split(':')
1515

16-
if (parts.length !== 3) {
17-
throw { message: 'Invalid bearer token format', status: 401 }
18-
}
16+
if (parts.length !== 3)
17+
throw new HttpError(401, 'Invalid bearer token format')
1918

2019
const tokenId = Number(parts[0])
2120
const teamId = parts[1] as string
2221
const plainString = parts[2] as string
2322

2423
const team = await Team.find(Number(teamId))
2524

26-
if (!team) {
27-
throw new Error(JSON.stringify({ message: 'Invalid bearer token', status: 401 }))
28-
}
25+
if (!team)
26+
throw new HttpError(401, 'Invalid bearer token')
2927

3028
const accessTokens = await team.teamAccessTokens()
3129

32-
if (!accessTokens.length) {
33-
throw new Error(JSON.stringify({ message: 'Invalid bearer token', status: 401 }))
34-
}
30+
if (!accessTokens.length)
31+
throw new HttpError(401, 'Invalid bearer token')
3532

3633
const accessTokenIds = accessTokens.map(accessToken => accessToken.id)
3734

38-
if (!accessTokenIds.includes(tokenId)) {
39-
throw new Error(JSON.stringify({ message: 'Invalid bearer token', status: 401 }))
40-
}
35+
if (!accessTokenIds.includes(tokenId))
36+
throw new HttpError(401, 'Invalid bearer token')
4137

4238
const teamBearerToken = await AccessToken.where('token', plainString).first()
4339

44-
if (!teamBearerToken) {
45-
throw new Error(JSON.stringify({ message: 'Invalid bearer token', status: 401 }))
46-
}
40+
if (!teamBearerToken)
41+
throw new HttpError(401, 'Invalid bearer token')
4742
},
4843
})

app/Models/User.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import type { Model } from '@stacksjs/types'
2+
import type { UserModel } from '../../storage/framework/orm/src/models/User'
23
// soon, these will be auto-imported
34
import { faker } from '@stacksjs/faker'
45
import { capitalize } from '@stacksjs/strings'
@@ -107,7 +108,7 @@ export default {
107108
},
108109

109110
get: {
110-
fullName: (user: User) => capitalize(user.name),
111+
fullName: (user: UserModel) => capitalize(user.name || ''),
111112
},
112113

113114
set: {

resources/views/auth/login.vue

Lines changed: 1 addition & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
<script setup lang="ts">
2-
import { startAuthentication } from '@simplewebauthn/browser'
32
// Imports
43
import { ref } from 'vue'
54
import { useRouter } from 'vue-router'
65
76
// Reactive state for form inputs and messages
87
const email = ref('')
98
const password = ref('')
10-
const successMessage = ref('')
119
const errorMessage = ref('')
1210
1311
// Router instance
@@ -51,48 +49,6 @@ async function login() {
5149
password.value = ''
5250
}
5351
}
54-
55-
// Method to handle passkey login
56-
async function loginPasskey() {
57-
// Reset success/error messages
58-
successMessage.value = ''
59-
errorMessage.value = ''
60-
61-
try {
62-
// Fetch authentication options based on email
63-
const resp = await fetch(`http://localhost:3008/generate-authentication-options?email=${email.value}`)
64-
const options: any = await resp.json()
65-
66-
// Start the WebAuthn authentication process
67-
const asseResp = await startAuthentication(options)
68-
69-
// Verify the authentication response with the backend
70-
const verificationResp: any = await fetch('http://localhost:3008/verify-authentication', {
71-
method: 'POST',
72-
headers: {
73-
'Content-Type': 'application/json',
74-
},
75-
body: JSON.stringify({
76-
res: asseResp,
77-
email: email.value,
78-
challenge: options.challenge,
79-
}),
80-
})
81-
82-
const verificationJSON = await verificationResp.json()
83-
84-
if (verificationJSON?.verified) {
85-
successMessage.value = 'Authentication successful!'
86-
router.push({ path: '/dashboard' })
87-
}
88-
else {
89-
errorMessage.value = `Authentication failed. Response: ${JSON.stringify(verificationJSON)}`
90-
}
91-
}
92-
catch (error) {
93-
errorMessage.value = 'An error occurred during passkey authentication'
94-
}
95-
}
9652
</script>
9753

9854
<template>
@@ -133,7 +89,7 @@ async function loginPasskey() {
13389
</div>
13490

13591
<div>
136-
<button type="submit" class="w-full flex justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm text-white font-semibold leading-6 shadow-sm hover:bg-indigo-500 focus-visible:outline-2 focus-visible:outline-indigo-600 focus-visible:outline-offset-2 focus-visible:outline" @click="loginPasskey" @click="login">
92+
<button type="submit" class="w-full flex justify-center rounded-md bg-indigo-600 px-3 py-1.5 text-sm text-white font-semibold leading-6 shadow-sm hover:bg-indigo-500 focus-visible:outline-2 focus-visible:outline-indigo-600 focus-visible:outline-offset-2 focus-visible:outline" @click="login">
13793
Sign in
13894
</button>
13995
</div>
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
import type { UserRequestType } from '../../types/requests'
21
import { Action } from '@stacksjs/actions'
32
import User from '../../orm/src/models/User'
43

54
export default new Action({
65
name: 'User Index',
76
description: 'User Index ORM Action',
87
method: 'GET',
9-
async handle(request: UserRequestType) {
8+
async handle() {
109
return await User.all()
1110
},
1211
})

storage/framework/core/auth/src/authentication.ts

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { HttpError } from '@stacksjs/error-handling'
12
import { request } from '@stacksjs/router'
23
import { verifyHash } from '@stacksjs/security'
34
import AccessToken from '../../../orm/src/models/AccessToken'
@@ -53,9 +54,8 @@ export async function team(): Promise<TeamModel | undefined> {
5354

5455
const parts = bearerToken.split(':')
5556

56-
if (parts.length !== 3) {
57-
throw { message: 'Invalid bearer token format', status: 401 }
58-
}
57+
if (parts.length !== 3)
58+
throw new HttpError(401, 'Invalid bearer token format')
5959

6060
const tokenId = Number(parts[0])
6161
const teamId = parts[1]
@@ -83,9 +83,8 @@ export async function authToken(): Promise<AuthToken | undefined> {
8383

8484
const tokenId = accessToken?.id
8585

86-
if (!accessToken) {
87-
throw { error: 'Error generating token!' }
88-
}
86+
if (!accessToken)
87+
throw new HttpError(500, 'Error generating token!')
8988

9089
return `${tokenId}:${team.id}:${accessToken.token}`
9190
}

storage/framework/core/cache/src/drivers/dynamodb.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,21 @@ const client = new BentoCache({
3030

3131
export const dynamodb: CacheDriver = {
3232
async set(key: string, value: string, ttl?: number): Promise<void> {
33-
await client.set({
33+
const data: { key: string, value: string, gracePeriod?: { enabled: boolean, duration: string } } = {
3434
key,
3535
value,
36-
gracePeriod: { enabled: true, duration: '5m' },
37-
})
36+
}
37+
38+
if (ttl) {
39+
data.gracePeriod = {
40+
enabled: true,
41+
duration: `${ttl}m`,
42+
}
43+
}
44+
45+
await client.set(data)
3846
},
39-
async setForever(key: string, value: string, ttl?: number): Promise<void> {
47+
async setForever(key: string, value: string): Promise<void> {
4048
await client.setForever({
4149
key,
4250
value,

storage/framework/core/cache/src/drivers/filesystem.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,21 @@ const client = new BentoCache({
1616

1717
export const fileSystem: CacheDriver = {
1818
async set(key: string, value: string, ttl?: number): Promise<void> {
19-
await client.set({
19+
const data: { key: string, value: string, gracePeriod?: { enabled: boolean, duration: string } } = {
2020
key,
2121
value,
22-
gracePeriod: { enabled: true, duration: '5m' },
23-
})
22+
}
23+
24+
if (ttl) {
25+
data.gracePeriod = {
26+
enabled: true,
27+
duration: `${ttl}m`,
28+
}
29+
}
30+
31+
await client.set(data)
2432
},
25-
async setForever(key: string, value: string, ttl?: number): Promise<void> {
33+
async setForever(key: string, value: string): Promise<void> {
2634
await client.setForever({
2735
key,
2836
value,

storage/framework/core/cache/src/drivers/memory.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,21 @@ const client = new BentoCache({
1616

1717
export const memory: CacheDriver = {
1818
async set(key: string, value: string, ttl?: number): Promise<void> {
19-
await client.set({
19+
const data: { key: string, value: string, gracePeriod?: { enabled: boolean, duration: string } } = {
2020
key,
2121
value,
22-
gracePeriod: { enabled: true, duration: '5m' },
23-
})
22+
}
23+
24+
if (ttl) {
25+
data.gracePeriod = {
26+
enabled: true,
27+
duration: `${ttl}m`,
28+
}
29+
}
30+
31+
await client.set(data)
2432
},
25-
async setForever(key: string, value: string, ttl?: number): Promise<void> {
33+
async setForever(key: string, value: string): Promise<void> {
2634
await client.setForever({
2735
key,
2836
value,

storage/framework/core/cache/src/drivers/redis.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,21 @@ const client = new BentoCache({
1515

1616
export const redis: CacheDriver = {
1717
async set(key: string, value: string, ttl?: number): Promise<void> {
18-
await client.set({
18+
const data: { key: string, value: string, gracePeriod?: { enabled: boolean, duration: string } } = {
1919
key,
2020
value,
21-
gracePeriod: { enabled: true, duration: '5m' },
22-
})
21+
}
22+
23+
if (ttl) {
24+
data.gracePeriod = {
25+
enabled: true,
26+
duration: `${ttl}m`,
27+
}
28+
}
29+
30+
await client.set(data)
2331
},
24-
async setForever(key: string, value: string, ttl?: number): Promise<void> {
32+
async setForever(key: string, value: string): Promise<void> {
2533
await client.setForever({
2634
key,
2735
value,

0 commit comments

Comments
 (0)