@stacksjs/auth 0.70.23 → 0.70.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +155 -5168
- package/dist/src/authentication.d.ts +43 -0
- package/dist/src/authenticator.d.ts +17 -0
- package/dist/src/authorizable.d.ts +77 -0
- package/dist/src/client.d.ts +2 -0
- package/dist/src/email-verification.d.ts +29 -0
- package/dist/src/gate.d.ts +161 -0
- package/dist/src/index.d.ts +29 -0
- package/dist/src/middleware.d.ts +14 -0
- package/dist/src/passkey.d.ts +46 -0
- package/dist/src/password/reset.d.ts +10 -0
- package/dist/src/policy.d.ts +33 -0
- package/dist/src/rate-limiter.d.ts +6 -0
- package/dist/src/rbac.d.ts +219 -0
- package/dist/src/register.d.ts +3 -0
- package/dist/src/session-auth.d.ts +30 -0
- package/dist/src/tokens.d.ts +251 -0
- package/dist/src/user.d.ts +34 -0
- package/package.json +22 -12
- package/dist/authentication.d.ts +0 -150
- package/dist/authenticator.d.ts +0 -6
- package/dist/index.d.ts +0 -3
- package/dist/passkey.d.ts +0 -64
package/dist/authentication.d.ts
DELETED
|
@@ -1,150 +0,0 @@
|
|
|
1
|
-
import type { UserModel, UsersTable } from '../../../orm/src/models/User';
|
|
2
|
-
|
|
3
|
-
declare interface Credentials {
|
|
4
|
-
password: string | undefined
|
|
5
|
-
email: string | undefined
|
|
6
|
-
[key: string]: string | undefined
|
|
7
|
-
}
|
|
8
|
-
declare type AuthToken = `${number}:${number}:${string}`
|
|
9
|
-
|
|
10
|
-
const authConfig = { username: 'email', password: 'password' }
|
|
11
|
-
|
|
12
|
-
let authUser: UserModel | null = null
|
|
13
|
-
|
|
14
|
-
export async function attempt(credentials: Credentials): Promise<boolean> {
|
|
15
|
-
let hashCheck = false
|
|
16
|
-
|
|
17
|
-
const user = await User.where(authConfig.username as keyof UsersTable, credentials[authConfig.username]).first()
|
|
18
|
-
const authPass = credentials[authConfig.password]
|
|
19
|
-
|
|
20
|
-
if (typeof authPass === 'string' && user?.password)
|
|
21
|
-
hashCheck = await verifyHash(authPass, user.password, 'bcrypt')
|
|
22
|
-
|
|
23
|
-
if (hashCheck && user) {
|
|
24
|
-
authUser = user
|
|
25
|
-
return true
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return false
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export async function createAccessToken(user: UserModel, teamId?: number): Promise<AuthToken> {
|
|
32
|
-
const token = randomBytes(40).toString('hex')
|
|
33
|
-
|
|
34
|
-
const accessToken = await AccessToken.create({
|
|
35
|
-
team_id: teamId,
|
|
36
|
-
token,
|
|
37
|
-
name: 'auth-token',
|
|
38
|
-
expires_at: new Date(Date.now() + 1000 * 60 * 60 * 24 * 30),
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
if (!accessToken?.id)
|
|
42
|
-
throw new HttpError(500, 'Failed to create access token')
|
|
43
|
-
|
|
44
|
-
return `${accessToken.id}:${teamId || 0}:${token}`
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export async function login(credentials: Credentials): Promise<{ token: AuthToken } | null> {
|
|
48
|
-
const isValid = await attempt(credentials)
|
|
49
|
-
|
|
50
|
-
if (!isValid || !authUser)
|
|
51
|
-
return null
|
|
52
|
-
|
|
53
|
-
const teams = await authUser.userTeams()
|
|
54
|
-
const primaryTeam = teams[0]
|
|
55
|
-
|
|
56
|
-
const token = await createAccessToken(authUser, primaryTeam?.id)
|
|
57
|
-
return { token }
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export async function validateToken(token: string): Promise<boolean> {
|
|
61
|
-
const parts = token.split(':')
|
|
62
|
-
|
|
63
|
-
if (parts.length !== 3)
|
|
64
|
-
return false
|
|
65
|
-
|
|
66
|
-
const [tokenId, teamId, plainToken] = parts
|
|
67
|
-
|
|
68
|
-
const accessToken = await AccessToken.where('id', Number(tokenId))
|
|
69
|
-
.where('token', plainToken)
|
|
70
|
-
.where('team_id', Number(teamId))
|
|
71
|
-
.first()
|
|
72
|
-
|
|
73
|
-
if (!accessToken)
|
|
74
|
-
return false
|
|
75
|
-
|
|
76
|
-
if (accessToken.expires_at && new Date(accessToken.expires_at) < new Date())
|
|
77
|
-
return false
|
|
78
|
-
|
|
79
|
-
await AccessToken.where('id', accessToken.id).update({
|
|
80
|
-
last_used_at: new Date(),
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
return true
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
export async function getUserFromToken(token: string): Promise<UserModel | undefined> {
|
|
87
|
-
const parts = token.split(':')
|
|
88
|
-
|
|
89
|
-
if (parts.length !== 3)
|
|
90
|
-
return undefined
|
|
91
|
-
|
|
92
|
-
const [tokenId] = parts
|
|
93
|
-
|
|
94
|
-
const accessToken = await AccessToken.where('id', Number(tokenId)).first()
|
|
95
|
-
|
|
96
|
-
if (!accessToken?.user_id)
|
|
97
|
-
return undefined
|
|
98
|
-
|
|
99
|
-
return await User.find(accessToken.user_id)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export async function team(): Promise<TeamModel | undefined> {
|
|
103
|
-
if (authUser) {
|
|
104
|
-
const teams = await authUser.userTeams()
|
|
105
|
-
return teams[0]
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const bearerToken = request.bearerToken()
|
|
109
|
-
|
|
110
|
-
if (!bearerToken)
|
|
111
|
-
return undefined
|
|
112
|
-
|
|
113
|
-
const parts = bearerToken.split(':')
|
|
114
|
-
|
|
115
|
-
if (parts.length !== 3)
|
|
116
|
-
throw new HttpError(401, 'Invalid bearer token format')
|
|
117
|
-
|
|
118
|
-
const tokenId = Number(parts[0])
|
|
119
|
-
const teamId = parts[1]
|
|
120
|
-
const plainString = parts[2]
|
|
121
|
-
|
|
122
|
-
const accessToken = await AccessToken.where('id', Number(tokenId))
|
|
123
|
-
.where('token', plainString)
|
|
124
|
-
.first()
|
|
125
|
-
|
|
126
|
-
if (Number(teamId) !== Number(accessToken?.team_id))
|
|
127
|
-
return undefined
|
|
128
|
-
|
|
129
|
-
return await Team.find(Number(accessToken?.team_id))
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
export async function revokeToken(token: string): Promise<void> {
|
|
133
|
-
const parts = token.split(':')
|
|
134
|
-
|
|
135
|
-
if (parts.length !== 3)
|
|
136
|
-
return
|
|
137
|
-
|
|
138
|
-
const [tokenId] = parts
|
|
139
|
-
|
|
140
|
-
await AccessToken.where('id', Number(tokenId)).delete()
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
export async function logout(): Promise<void> {
|
|
144
|
-
const bearerToken = request.bearerToken()
|
|
145
|
-
|
|
146
|
-
if (bearerToken)
|
|
147
|
-
await revokeToken(bearerToken)
|
|
148
|
-
|
|
149
|
-
authUser = null
|
|
150
|
-
}
|
package/dist/authenticator.d.ts
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
export declare function generateTwoFactorSecret(): string;
|
|
2
|
-
export declare type Token = string
|
|
3
|
-
export type Secret = string
|
|
4
|
-
export declare function generateTwoFactorToken(): Token;
|
|
5
|
-
export declare function verifyTwoFactorCode(token: Token, secret: Secret): boolean;
|
|
6
|
-
export declare function generateQrCode(): void;
|
package/dist/index.d.ts
DELETED
package/dist/passkey.d.ts
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import type { Insertable } from '@stacksjs/database';
|
|
2
|
-
import type { UserModel } from '../../../orm/src/models/User';
|
|
3
|
-
import type { VerifiedRegistrationResponse } from '@simplewebauthn/server';
|
|
4
|
-
|
|
5
|
-
export declare type * from '@simplewebauthn/types'
|
|
6
|
-
|
|
7
|
-
type PasskeyInsertable = Insertable<PasskeyAttribute>
|
|
8
|
-
|
|
9
|
-
export interface PasskeyAttribute {
|
|
10
|
-
id: string
|
|
11
|
-
cred_public_key: string
|
|
12
|
-
user_id: number
|
|
13
|
-
webauthn_user_id: string
|
|
14
|
-
counter: number
|
|
15
|
-
credential_type: string
|
|
16
|
-
device_type: string
|
|
17
|
-
backup_eligible: boolean
|
|
18
|
-
backup_status: boolean
|
|
19
|
-
transports?: string
|
|
20
|
-
created_at?: Date
|
|
21
|
-
last_used_at: string
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export async function getUserPasskeys(userId: number): Promise<PasskeyAttribute[]> {
|
|
25
|
-
return await db.selectFrom('passkeys').selectAll().where('user_id', '=', userId).execute()
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export async function getUserPasskey(userId: number, passkeyId: string): Promise<PasskeyAttribute | undefined> {
|
|
29
|
-
return await db
|
|
30
|
-
.selectFrom('passkeys')
|
|
31
|
-
.selectAll()
|
|
32
|
-
.where('id', '=', passkeyId)
|
|
33
|
-
.where('user_id', '=', userId)
|
|
34
|
-
.executeTakeFirst()
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export async function setCurrentRegistrationOptions(
|
|
38
|
-
user: UserModel,
|
|
39
|
-
verified: VerifiedRegistrationResponse,
|
|
40
|
-
): Promise<void> {
|
|
41
|
-
const passkeyData: PasskeyInsertable = {
|
|
42
|
-
id: verified.registrationInfo?.credential.id || '',
|
|
43
|
-
cred_public_key: JSON.stringify(verified.registrationInfo?.credential.publicKey),
|
|
44
|
-
user_id: user.id as number,
|
|
45
|
-
webauthn_user_id: user.email || '',
|
|
46
|
-
counter: verified.registrationInfo?.credential.counter || 0,
|
|
47
|
-
credential_type: verified.registrationInfo?.credentialType || '',
|
|
48
|
-
device_type: verified.registrationInfo?.credentialDeviceType || '',
|
|
49
|
-
backup_eligible: false,
|
|
50
|
-
backup_status: verified.registrationInfo?.credentialBackedUp || false,
|
|
51
|
-
transports: JSON.stringify(['internal']),
|
|
52
|
-
last_used_at: formatDateTime(),
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
await db.insertInto('passkeys').values(passkeyData).executeTakeFirstOrThrow()
|
|
56
|
-
}
|
|
57
|
-
declare function formatDateTime(): string;
|
|
58
|
-
|
|
59
|
-
export {
|
|
60
|
-
generateAuthenticationOptions,
|
|
61
|
-
generateRegistrationOptions,
|
|
62
|
-
verifyAuthenticationResponse,
|
|
63
|
-
verifyRegistrationResponse,
|
|
64
|
-
} from '@simplewebauthn/server'
|