@stacksjs/auth 0.70.83 → 0.70.85

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.
Files changed (2) hide show
  1. package/dist/index.js +61 -61
  2. package/package.json +4 -3
package/dist/index.js CHANGED
@@ -1,110 +1,110 @@
1
1
  // @bun
2
- var Y$=Object.defineProperty;var K$=($)=>$;function L$($,W){this[$]=K$.bind(null,W)}var e0=($,W)=>{for(var Z in W)Y$($,Z,{get:W[Z],enumerable:!0,configurable:!0,set:L$.bind(W,Z)})};var $1=($,W)=>()=>($&&(W=$($=0)),W);var D0=import.meta.require;var K1={};e0(K1,{validateRefreshToken:()=>x$,tokens:()=>U$,tokenCant:()=>C$,tokenCanAny:()=>v$,tokenCanAll:()=>P$,tokenCan:()=>X1,tokenAbilities:()=>S$,token:()=>q$,revokeTokenById:()=>T$,revokeToken:()=>y$,revokeRefreshToken:()=>R$,revokeOtherTokens:()=>w$,revokeClient:()=>h$,revokeAllTokens:()=>j0,revokeAllRefreshTokens:()=>Y1,refreshToken:()=>E$,parseScopes:()=>w,isIssuedBeforePasswordChange:()=>d,getPasswordChangedAt:()=>s,findToken:()=>G1,findClient:()=>k$,deleteRevokedTokens:()=>I$,deleteRevokedRefreshTokens:()=>N$,deleteExpiredTokens:()=>f$,deleteExpiredRefreshTokens:()=>A$,currentAccessToken:()=>n,createToken:()=>w0,createClient:()=>g$,clients:()=>b$});import{createHash as _$,randomBytes as z$}from"crypto";import{db as B}from"@stacksjs/database";import{HttpError as X0}from"@stacksjs/error-handling";import{getCurrentRequest as D$}from"@stacksjs/router";import{env as j$}from"@stacksjs/env";import{sqlHelpers as H$}from"@stacksjs/database";function z($){return J1.param($)}function h($){return _$("sha256").update($).digest("hex")}function Q1($){let W=$.indexOf(":"),Z=W===-1?$:$.substring(0,W);return h(Z)}function Y0($=40){return z$($).toString("hex")}async function s($,W=B){if($===null||$===void 0)return null;try{let J=(await W.unsafe(`
2
+ var r1=Object.defineProperty;var s1=($)=>$;function e1($,W){this[$]=s1.bind(null,W)}var d0=($,W)=>{for(var Z in W)r1($,Z,{get:W[Z],enumerable:!0,configurable:!0,set:e1.bind(W,Z)})};var n0=($,W)=>()=>($&&(W=$($=0)),W);var _0=import.meta.require;var $1={};d0($1,{validateRefreshToken:()=>j$,tokens:()=>V$,tokenCant:()=>B$,tokenCanAny:()=>_$,tokenCanAll:()=>O$,tokenCan:()=>s0,tokenAbilities:()=>z$,token:()=>F$,revokeTokenById:()=>C$,revokeToken:()=>q$,revokeRefreshToken:()=>H$,revokeOtherTokens:()=>P$,revokeClient:()=>A$,revokeAllTokens:()=>z0,revokeAllRefreshTokens:()=>e0,refreshToken:()=>D$,parseScopes:()=>w,isIssuedBeforePasswordChange:()=>u,getPasswordChangedAt:()=>a,findToken:()=>r0,findClient:()=>x$,deleteRevokedTokens:()=>E$,deleteRevokedRefreshTokens:()=>U$,deleteExpiredTokens:()=>v$,deleteExpiredRefreshTokens:()=>M$,currentAccessToken:()=>l,createToken:()=>N0,createClient:()=>R$,clients:()=>S$});import{createHash as Q$,randomBytes as G$}from"crypto";import{db as B}from"@stacksjs/database";import{HttpError as Q0}from"@stacksjs/error-handling";import{getCurrentRequest as X$}from"@stacksjs/router";import{env as Y$}from"@stacksjs/env";import{sqlHelpers as K$}from"@stacksjs/database";function z($){return o0.param($)}function b($){return Q$("sha256").update($).digest("hex")}function a0($){let W=$.indexOf(":"),Z=W===-1?$:$.substring(0,W);return b(Z)}function G0($=40){return G$($).toString("hex")}async function a($,W=B){if($===null||$===void 0)return null;try{let J=(await W.unsafe(`
3
3
  SELECT password_changed_at FROM users WHERE id = ${z(1)} LIMIT 1
4
- `,[$]))[0]?.password_changed_at;if(J===null||J===void 0)return null;let Q=new Date(String(J));return Number.isNaN(Q.getTime())?null:Q}catch{return null}}function d($,W){if(!W)return!1;if($===null||$===void 0)return!1;let Z=new Date(String($));if(Number.isNaN(Z.getTime()))return!1;return Z.getTime()<W.getTime()}async function U$($){return(await B.unsafe(`
4
+ `,[$]))[0]?.password_changed_at;if(J===null||J===void 0)return null;let Q=new Date(String(J));return Number.isNaN(Q.getTime())?null:Q}catch{return null}}function u($,W){if(!W)return!1;if($===null||$===void 0)return!1;let Z=new Date(String($));if(Number.isNaN(Z.getTime()))return!1;return Z.getTime()<W.getTime()}async function V$($){return(await B.unsafe(`
5
5
  SELECT t.*, c.provider as client_provider
6
6
  FROM oauth_access_tokens t
7
7
  LEFT JOIN oauth_clients c ON t.oauth_client_id = c.id
8
8
  WHERE t.user_id = ${z(1)}
9
- AND t.revoked = ${K0}
9
+ AND t.revoked = ${X0}
10
10
  ORDER BY t.created_at DESC
11
- `,[$])).map((Z)=>({id:Z.id,userId:Z.user_id,clientId:Z.oauth_client_id,name:Z.name||"access-token",scopes:w(Z.scopes),revoked:!!Z.revoked,expiresAt:Z.expires_at?new Date(Z.expires_at):null,createdAt:new Date(Z.created_at),updatedAt:Z.updated_at?new Date(Z.updated_at):new Date}))}async function G1($){let W=Q1($),J=(await B.unsafe(`
11
+ `,[$])).map((Z)=>({id:Z.id,userId:Z.user_id,clientId:Z.oauth_client_id,name:Z.name||"access-token",scopes:w(Z.scopes),revoked:!!Z.revoked,expiresAt:Z.expires_at?new Date(Z.expires_at):null,createdAt:new Date(Z.created_at),updatedAt:Z.updated_at?new Date(Z.updated_at):new Date}))}async function r0($){let W=a0($),J=(await B.unsafe(`
12
12
  SELECT * FROM oauth_access_tokens
13
13
  WHERE token = ${z(1)}
14
- AND revoked = ${K0}
15
- AND (expires_at IS NULL OR expires_at > ${U})
14
+ AND revoked = ${X0}
15
+ AND (expires_at IS NULL OR expires_at > ${M})
16
16
  LIMIT 1
17
- `,[W]))[0];if(!J)return null;if(d(J.created_at,await s(J.user_id)))return null;return{id:J.id,userId:J.user_id,clientId:J.oauth_client_id,name:J.name||"access-token",scopes:w(J.scopes),revoked:!!J.revoked,expiresAt:J.expires_at?new Date(J.expires_at):null,createdAt:new Date(J.created_at),updatedAt:J.updated_at?new Date(J.updated_at):new Date}}async function n(){let $=D$();if(!$)return null;let W=$._currentAccessToken;if(W)return W;let Z=$.bearerToken?.();if(!Z)return null;let J=await G1(Z);if(J)$._currentAccessToken=J;return J}async function X1($){let W=await n();if(!W)return!1;if(W.scopes.includes("*"))return!0;return W.scopes.includes($)}async function C$($){return!await X1($)}async function P$($){let W=await n();if(!W)return!1;if(W.scopes.includes("*"))return!0;return $.every((Z)=>W.scopes.includes(Z))}async function v$($){let W=await n();if(!W)return!1;if(W.scopes.includes("*"))return!0;return $.some((Z)=>W.scopes.includes(Z))}async function S$(){return(await n())?.scopes||[]}async function w0($,W="access-token",Z=["*"],J={}){let{expiresInMinutes:Q=60,withRefreshToken:G=!0,refreshExpiresInDays:X=30}=J,Y=(await B.unsafe(`
18
- SELECT id FROM oauth_clients WHERE personal_access_client = ${v} LIMIT 1
19
- `))[0];if(!Y)throw new X0(500,"No personal access client found. Run ./buddy auth:setup first.");let L=Y0(40),O=h(L),_=new Date;if(_.setMinutes(_.getMinutes()+Q),r)await B.unsafe(`
17
+ `,[W]))[0];if(!J)return null;if(u(J.created_at,await a(J.user_id)))return null;return{id:J.id,userId:J.user_id,clientId:J.oauth_client_id,name:J.name||"access-token",scopes:w(J.scopes),revoked:!!J.revoked,expiresAt:J.expires_at?new Date(J.expires_at):null,createdAt:new Date(J.created_at),updatedAt:J.updated_at?new Date(J.updated_at):new Date}}async function l(){let $=X$();if(!$)return null;let W=$._currentAccessToken;if(W)return W;let Z=$.bearerToken?.();if(!Z)return null;let J=await r0(Z);if(J)$._currentAccessToken=J;return J}async function s0($){let W=await l();if(!W)return!1;if(W.scopes.includes("*"))return!0;return W.scopes.includes($)}async function B$($){return!await s0($)}async function O$($){let W=await l();if(!W)return!1;if(W.scopes.includes("*"))return!0;return $.every((Z)=>W.scopes.includes(Z))}async function _$($){let W=await l();if(!W)return!1;if(W.scopes.includes("*"))return!0;return $.some((Z)=>W.scopes.includes(Z))}async function z$(){return(await l())?.scopes||[]}async function N0($,W="access-token",Z=["*"],J={}){let{expiresInMinutes:Q=60,withRefreshToken:G=!0,refreshExpiresInDays:X=30}=J,Y=(await B.unsafe(`
18
+ SELECT id FROM oauth_clients WHERE personal_access_client = ${P} LIMIT 1
19
+ `))[0];if(!Y)throw new Q0(500,"No personal access client found. Run ./buddy auth:setup first.");let L=G0(40),O=b(L),_=new Date;if(_.setMinutes(_.getMinutes()+Q),o)await B.unsafe(`
20
20
  INSERT INTO oauth_access_tokens (user_id, oauth_client_id, token, name, scopes, revoked, expires_at, created_at, updated_at)
21
21
  VALUES ($1, $2, $3, $4, $5, false, $6, NOW(), NOW())
22
22
  `,[$,Y.id,O,W,JSON.stringify(Z),_.toISOString()]);else await B.unsafe(`
23
23
  INSERT INTO oauth_access_tokens (user_id, oauth_client_id, token, name, scopes, revoked, expires_at, created_at, updated_at)
24
- VALUES (?, ?, ?, ?, ?, 0, ?, ${U}, ${U})
24
+ VALUES (?, ?, ?, ?, ?, 0, ?, ${M}, ${M})
25
25
  `,[$,Y.id,O,W,JSON.stringify(Z),_.toISOString()]);let F=(await B.unsafe(`
26
26
  SELECT * FROM oauth_access_tokens WHERE token = ${z(1)} LIMIT 1
27
- `,[O]))[0];if(!F)throw new X0(500,"Failed to create access token \u2014 inserted row not found");let H={id:F.id,userId:F.user_id,clientId:F.oauth_client_id,name:F.name,scopes:w(F.scopes),revoked:!1,expiresAt:_,createdAt:new Date(F.created_at),updatedAt:new Date(F.updated_at)},P;if(G){P=Y0(40);let T=h(P),A=new Date;if(A.setDate(A.getDate()+X),r)await B.unsafe(`
27
+ `,[O]))[0];if(!F)throw new Q0(500,"Failed to create access token \u2014 inserted row not found");let j={id:F.id,userId:F.user_id,clientId:F.oauth_client_id,name:F.name,scopes:w(F.scopes),revoked:!1,expiresAt:_,createdAt:new Date(F.created_at),updatedAt:new Date(F.updated_at)},C;if(G){C=G0(40);let N=b(C),R=new Date;if(R.setDate(R.getDate()+X),o)await B.unsafe(`
28
28
  INSERT INTO oauth_refresh_tokens (access_token_id, token, revoked, expires_at, created_at)
29
29
  VALUES ($1, $2, false, $3, NOW())
30
- `,[H.id,T,A.toISOString()]);else await B.unsafe(`
30
+ `,[j.id,N,R.toISOString()]);else await B.unsafe(`
31
31
  INSERT INTO oauth_refresh_tokens (access_token_id, token, revoked, expires_at, created_at)
32
- VALUES (?, ?, 0, ?, ${U})
33
- `,[H.id,T,A.toISOString()])}return{accessToken:H,plainTextToken:L,refreshToken:P,expiresIn:Q*60}}async function E$($,W={}){let{expiresInMinutes:Z=60,refreshExpiresInDays:J=30}=W,Q=h($);return await B.transaction(async(G)=>{let X=G,Y=(await X.unsafe(`
32
+ VALUES (?, ?, 0, ?, ${M})
33
+ `,[j.id,N,R.toISOString()])}return{accessToken:j,plainTextToken:L,refreshToken:C,expiresIn:Q*60}}async function D$($,W={}){let{expiresInMinutes:Z=60,refreshExpiresInDays:J=30}=W,Q=b($);return await B.transaction(async(G)=>{let X=G,Y=(await X.unsafe(`
34
34
  SELECT r.*, t.user_id, t.oauth_client_id, t.name, t.scopes
35
35
  FROM oauth_refresh_tokens r
36
36
  JOIN oauth_access_tokens t ON r.access_token_id = t.id
37
37
  WHERE r.token = ${z(1)}
38
- AND r.revoked = ${K0}
39
- AND (r.expires_at IS NULL OR r.expires_at > ${U})
38
+ AND r.revoked = ${X0}
39
+ AND (r.expires_at IS NULL OR r.expires_at > ${M})
40
40
  LIMIT 1
41
- `,[Q]))[0];if(!Y)throw new X0(401,"Invalid or expired refresh token");if(d(Y.created_at,await s(Y.user_id,X)))throw new X0(401,"Invalid or expired refresh token");await X.unsafe(`
41
+ `,[Q]))[0];if(!Y)throw new Q0(401,"Invalid or expired refresh token");if(u(Y.created_at,await a(Y.user_id,X)))throw new Q0(401,"Invalid or expired refresh token");await X.unsafe(`
42
42
  UPDATE oauth_refresh_tokens
43
- SET revoked = ${v}
43
+ SET revoked = ${P}
44
44
  WHERE id = ${z(1)}
45
45
  `,[Y.id]),await X.unsafe(`
46
46
  UPDATE oauth_access_tokens
47
- SET revoked = ${v}
47
+ SET revoked = ${P}
48
48
  WHERE id = ${z(1)}
49
- `,[Y.access_token_id]);let L=Y0(40),O=h(L),_=new Date;if(_.setMinutes(_.getMinutes()+Z),r)await X.unsafe(`
49
+ `,[Y.access_token_id]);let L=G0(40),O=b(L),_=new Date;if(_.setMinutes(_.getMinutes()+Z),o)await X.unsafe(`
50
50
  INSERT INTO oauth_access_tokens (user_id, oauth_client_id, token, name, scopes, revoked, expires_at, created_at, updated_at)
51
51
  VALUES ($1, $2, $3, $4, $5, false, $6, NOW(), NOW())
52
52
  `,[Y.user_id,Y.oauth_client_id,O,Y.name,Y.scopes,_.toISOString()]);else await X.unsafe(`
53
53
  INSERT INTO oauth_access_tokens (user_id, oauth_client_id, token, name, scopes, revoked, expires_at, created_at, updated_at)
54
- VALUES (?, ?, ?, ?, ?, 0, ?, ${U}, ${U})
54
+ VALUES (?, ?, ?, ?, ?, 0, ?, ${M}, ${M})
55
55
  `,[Y.user_id,Y.oauth_client_id,O,Y.name,Y.scopes,_.toISOString()]);let F=(await X.unsafe(`
56
56
  SELECT * FROM oauth_access_tokens WHERE token = ${z(1)} LIMIT 1
57
- `,[O]))[0],H={id:F.id,userId:F.user_id,clientId:F.oauth_client_id,name:F.name,scopes:w(F.scopes),revoked:!1,expiresAt:_,createdAt:new Date(F.created_at),updatedAt:new Date(F.updated_at)};if(d(F.created_at,await s(Y.user_id,X)))throw new X0(401,"Invalid or expired refresh token");let P=Y0(40),T=h(P),A=new Date;if(A.setDate(A.getDate()+J),r)await X.unsafe(`
57
+ `,[O]))[0],j={id:F.id,userId:F.user_id,clientId:F.oauth_client_id,name:F.name,scopes:w(F.scopes),revoked:!1,expiresAt:_,createdAt:new Date(F.created_at),updatedAt:new Date(F.updated_at)};if(u(F.created_at,await a(Y.user_id,X)))throw new Q0(401,"Invalid or expired refresh token");let C=G0(40),N=b(C),R=new Date;if(R.setDate(R.getDate()+J),o)await X.unsafe(`
58
58
  INSERT INTO oauth_refresh_tokens (access_token_id, token, revoked, expires_at, created_at)
59
59
  VALUES ($1, $2, false, $3, NOW())
60
- `,[H.id,T,A.toISOString()]);else await X.unsafe(`
60
+ `,[j.id,N,R.toISOString()]);else await X.unsafe(`
61
61
  INSERT INTO oauth_refresh_tokens (access_token_id, token, revoked, expires_at, created_at)
62
- VALUES (?, ?, 0, ?, ${U})
63
- `,[H.id,T,A.toISOString()]);return{accessToken:H,plainTextToken:L,refreshToken:P,expiresIn:Z*60}})}async function x$($){let W=h($);return(await B.unsafe(`
62
+ VALUES (?, ?, 0, ?, ${M})
63
+ `,[j.id,N,R.toISOString()]);return{accessToken:j,plainTextToken:L,refreshToken:C,expiresIn:Z*60}})}async function j$($){let W=b($);return(await B.unsafe(`
64
64
  SELECT id FROM oauth_refresh_tokens
65
65
  WHERE token = ${z(1)}
66
- AND revoked = ${K0}
67
- AND (expires_at IS NULL OR expires_at > ${U})
66
+ AND revoked = ${X0}
67
+ AND (expires_at IS NULL OR expires_at > ${M})
68
68
  LIMIT 1
69
- `,[W])).length>0}async function R$($){let W=h($);await B.unsafe(`
69
+ `,[W])).length>0}async function H$($){let W=b($);await B.unsafe(`
70
70
  UPDATE oauth_refresh_tokens
71
- SET revoked = ${v}
71
+ SET revoked = ${P}
72
72
  WHERE token = ${z(1)}
73
- `,[W])}async function Y1($){await B.unsafe(`
73
+ `,[W])}async function e0($){await B.unsafe(`
74
74
  UPDATE oauth_refresh_tokens
75
- SET revoked = ${v}
75
+ SET revoked = ${P}
76
76
  WHERE access_token_id IN (
77
77
  SELECT id FROM oauth_access_tokens WHERE user_id = ${z(1)}
78
78
  )
79
- `,[$])}async function A$(){let $=await B.unsafe(`
79
+ `,[$])}async function M$(){let $=await B.unsafe(`
80
80
  DELETE FROM oauth_refresh_tokens
81
- WHERE expires_at < ${U}
82
- `);return $?.changes||$?.rowCount||0}async function N$($=7){let W=new Date;W.setDate(W.getDate()-$);let Z=await B.unsafe(`
81
+ WHERE expires_at < ${M}
82
+ `);return $?.changes||$?.rowCount||0}async function U$($=7){let W=new Date;W.setDate(W.getDate()-$);let Z=await B.unsafe(`
83
83
  DELETE FROM oauth_refresh_tokens
84
- WHERE revoked = ${v} AND created_at < ${z(1)}
85
- `,[W.toISOString()]);return Z?.changes||Z?.rowCount||0}async function y$($){let W=Q1($);await B.unsafe(`
84
+ WHERE revoked = ${P} AND created_at < ${z(1)}
85
+ `,[W.toISOString()]);return Z?.changes||Z?.rowCount||0}async function q$($){let W=a0($);await B.unsafe(`
86
86
  UPDATE oauth_refresh_tokens
87
- SET revoked = ${v}
87
+ SET revoked = ${P}
88
88
  WHERE access_token_id IN (
89
89
  SELECT id FROM oauth_access_tokens WHERE token = ${z(1)}
90
90
  )
91
91
  `,[W]),await B.unsafe(`
92
92
  UPDATE oauth_access_tokens
93
- SET revoked = ${v}, updated_at = ${U}
93
+ SET revoked = ${P}, updated_at = ${M}
94
94
  WHERE token = ${z(1)}
95
- `,[W])}async function T$($){await B.unsafe(`
95
+ `,[W])}async function C$($){await B.unsafe(`
96
96
  UPDATE oauth_refresh_tokens
97
- SET revoked = ${v}
97
+ SET revoked = ${P}
98
98
  WHERE access_token_id = ${z(1)}
99
99
  `,[$]),await B.unsafe(`
100
100
  UPDATE oauth_access_tokens
101
- SET revoked = ${v}, updated_at = ${U}
101
+ SET revoked = ${P}, updated_at = ${M}
102
102
  WHERE id = ${z(1)}
103
- `,[$])}async function j0($){await Y1($),await B.unsafe(`
103
+ `,[$])}async function z0($){await e0($),await B.unsafe(`
104
104
  UPDATE oauth_access_tokens
105
- SET revoked = ${v}, updated_at = ${U}
105
+ SET revoked = ${P}, updated_at = ${M}
106
106
  WHERE user_id = ${z(1)}
107
- `,[$])}async function w$($){let W=await n();if(!W)return j0($);if(r)await B.unsafe(`
107
+ `,[$])}async function P$($){let W=await l();if(!W)return z0($);if(o)await B.unsafe(`
108
108
  UPDATE oauth_refresh_tokens
109
109
  SET revoked = true
110
110
  WHERE access_token_id IN (
@@ -122,44 +122,44 @@ var Y$=Object.defineProperty;var K$=($)=>$;function L$($,W){this[$]=K$.bind(null
122
122
  )
123
123
  `,[$,W.id]),await B.unsafe(`
124
124
  UPDATE oauth_access_tokens
125
- SET revoked = 1, updated_at = ${U}
125
+ SET revoked = 1, updated_at = ${M}
126
126
  WHERE user_id = ? AND id != ?
127
- `,[$,W.id])}async function f$(){await B.unsafe(`
127
+ `,[$,W.id])}async function v$(){await B.unsafe(`
128
128
  DELETE FROM oauth_refresh_tokens
129
129
  WHERE access_token_id IN (
130
- SELECT id FROM oauth_access_tokens WHERE expires_at < ${U}
130
+ SELECT id FROM oauth_access_tokens WHERE expires_at < ${M}
131
131
  )
132
132
  `);let $=await B.unsafe(`
133
133
  DELETE FROM oauth_access_tokens
134
- WHERE expires_at < ${U}
135
- `);return $?.changes||$?.rowCount||0}async function I$($=7){let W=new Date;W.setDate(W.getDate()-$),await B.unsafe(`
134
+ WHERE expires_at < ${M}
135
+ `);return $?.changes||$?.rowCount||0}async function E$($=7){let W=new Date;W.setDate(W.getDate()-$),await B.unsafe(`
136
136
  DELETE FROM oauth_refresh_tokens
137
137
  WHERE access_token_id IN (
138
- SELECT id FROM oauth_access_tokens WHERE revoked = ${v} AND updated_at < ${z(1)}
138
+ SELECT id FROM oauth_access_tokens WHERE revoked = ${P} AND updated_at < ${z(1)}
139
139
  )
140
140
  `,[W.toISOString()]);let Z=await B.unsafe(`
141
141
  DELETE FROM oauth_access_tokens
142
- WHERE revoked = ${v} AND updated_at < ${z(1)}
143
- `,[W.toISOString()]);return Z?.changes||Z?.rowCount||0}async function b$($){return(await B.unsafe(`
142
+ WHERE revoked = ${P} AND updated_at < ${z(1)}
143
+ `,[W.toISOString()]);return Z?.changes||Z?.rowCount||0}async function S$($){return(await B.unsafe(`
144
144
  SELECT * FROM oauth_clients
145
- WHERE user_id = ${z(1)} AND revoked = ${K0}
145
+ WHERE user_id = ${z(1)} AND revoked = ${X0}
146
146
  ORDER BY created_at DESC
147
- `,[$])).map(f0)}async function k$($){let Z=(await B.unsafe(`
147
+ `,[$])).map(w0)}async function x$($){let Z=(await B.unsafe(`
148
148
  SELECT * FROM oauth_clients WHERE id = ${z(1)} LIMIT 1
149
- `,[$]))[0];return Z?f0(Z):null}async function g$($){let W=Y0(40);if(r)await B.unsafe(`
149
+ `,[$]))[0];return Z?w0(Z):null}async function R$($){let W=G0(40);if(o)await B.unsafe(`
150
150
  INSERT INTO oauth_clients (name, secret, provider, redirect, personal_access_client, password_client, revoked, created_at)
151
151
  VALUES ($1, $2, 'local', $3, $4, $5, false, NOW())
152
152
  `,[$.name,W,$.redirect,$.personalAccessClient||!1,$.passwordClient||!1]);else await B.unsafe(`
153
153
  INSERT INTO oauth_clients (name, secret, provider, redirect, personal_access_client, password_client, revoked, created_at)
154
- VALUES (?, ?, 'local', ?, ?, ?, 0, ${U})
154
+ VALUES (?, ?, 'local', ?, ?, ?, 0, ${M})
155
155
  `,[$.name,W,$.redirect,$.personalAccessClient?1:0,$.passwordClient?1:0]);let Z=await B.unsafe(`
156
156
  SELECT * FROM oauth_clients WHERE secret = ${z(1)} LIMIT 1
157
- `,[W]);return{client:f0(Z[0]),plainTextSecret:W}}async function h$($){await B.unsafe(`
157
+ `,[W]);return{client:w0(Z[0]),plainTextSecret:W}}async function A$($){await B.unsafe(`
158
158
  UPDATE oauth_clients
159
- SET revoked = ${v}, updated_at = ${U}
159
+ SET revoked = ${P}, updated_at = ${M}
160
160
  WHERE id = ${z(1)}
161
- `,[$])}function w($){if(!$)return[];if(Array.isArray($))return $;try{let W=JSON.parse($);return Array.isArray(W)?W:[]}catch{return[]}}function f0($){return{id:$.id,name:$.name,secret:$.secret,provider:$.provider,redirect:$.redirect,personalAccessClient:Boolean($.personal_access_client),passwordClient:Boolean($.password_client),revoked:Boolean($.revoked),createdAt:$.created_at?new Date($.created_at):new Date,updatedAt:$.updated_at?new Date($.updated_at):null}}var M$,J1,r,CZ,U,v,K0,q$;var L0=$1(()=>{M$=j$.DB_CONNECTION||"sqlite",J1=H$(M$),{isPostgres:r,isMysql:CZ,now:U,boolTrue:v,boolFalse:K0}=J1;q$=n});var I1={};e0(I1,{policy:()=>O0,none:()=>R1,inspect:()=>W0,hasPolicy:()=>y1,has:()=>N1,getPolicyFor:()=>A1,flush:()=>w1,denies:()=>x1,define:()=>P1,default:()=>UW,cannot:()=>S0,can:()=>v0,before:()=>v1,authorize:()=>x0,any:()=>_0,allows:()=>E1,all:()=>E0,after:()=>S1,abilities:()=>T1,Gate:()=>f1,AuthorizationResponse:()=>q,AuthorizationException:()=>B0});class q{isAllowed;message;code;constructor($,W,Z){this.isAllowed=$,this.message=W,this.code=Z}static allow($){return new q(!0,$)}static deny($,W){return new q(!1,$||"This action is unauthorized.",W)}allowed(){return this.isAllowed}denied(){return!this.isAllowed}authorize(){if(!this.isAllowed)throw new B0(this.message||"This action is unauthorized.",this.code)}}function P1($,W){C.gates.set($,W)}function O0($,W){let Z=typeof $==="string"?$:$.name;C.policies.set(Z,W)}function v1($){C.beforeCallbacks.push($)}function S1($){C.afterCallbacks.push($)}async function E1($,W,...Z){return Z0($,W,...Z)}async function x1($,W,...Z){return!await Z0($,W,...Z)}async function v0($,W,...Z){return Z0($,W,...Z)}async function S0($,W,...Z){return!await Z0($,W,...Z)}async function _0($,W,...Z){for(let J of $)if(await Z0(J,W,...Z))return!0;return!1}async function E0($,W,...Z){for(let J of $)if(!await Z0(J,W,...Z))return!1;return!0}async function R1($,W,...Z){return!await _0($,W,...Z)}async function x0($,W,...Z){let J=await W0($,W,...Z);if(!J.isAllowed)throw new B0(J.message,J.code);return J}async function W0($,W,...Z){for(let G of C.beforeCallbacks){let X=await G(W,$,Z);if(X===!0)return q.allow();if(X===!1)return q.deny()}let J=Z[0];if(J&&typeof J==="object"){let G=J.constructor?.name,X=C.policies.get(G);if(X){let K=new X;if(K.before){let L=await K.before(W,$);if(L===!0)return q.allow();if(L===!1)return q.deny()}let Y=K[$];if(Y){let L=await Y.call(K,W,...Z);return C1(L??!1)}}}let Q=C.gates.get($);if(Q){let G=await Q(W,...Z),X=C1(G);for(let K of C.afterCallbacks){let Y=await K(W,$,X.isAllowed,Z);if(typeof Y==="boolean")return Y?q.allow():q.deny()}return X}return q.deny(`No gate or policy defined for ability: ${$}`)}async function Z0($,W,...Z){return(await W0($,W,...Z)).isAllowed}function C1($){if($ instanceof q)return $;if(typeof $!=="boolean")throw TypeError(`[gate] Policy must return boolean or AuthorizationResponse; got ${typeof $}. If you returned a model/value by mistake, return \`true\`/\`false\` instead.`);return $?q.allow():q.deny()}function A1($){if(!$||typeof $!=="object")return null;let W=$.constructor?.name,Z=C.policies.get(W);if(Z)return new Z;return null}function N1($){return C.gates.has($)}function y1($){let W=typeof $==="string"?$:$.name;return C.policies.has(W)}function T1(){return Array.from(C.gates.keys())}function w1(){C.gates.clear(),C.policies.clear(),C.beforeCallbacks=[],C.afterCallbacks=[]}var B0,C,f1,UW;var J0=$1(()=>{B0=class B0 extends Error{code;status;constructor($="This action is unauthorized.",W,Z=403){super($);this.code=W;this.status=Z;this.name="AuthorizationException"}};C={gates:new Map,policies:new Map,beforeCallbacks:[],afterCallbacks:[]};f1={define:P1,policy:O0,before:v1,after:S1,allows:E1,denies:x1,can:v0,cannot:S0,any:_0,all:E0,none:R1,authorize:x0,inspect:W0,has:N1,hasPolicy:y1,abilities:T1,getPolicyFor:A1,flush:w1,AuthorizationResponse:q,AuthorizationException:B0},UW=f1});import{config as S}from"@stacksjs/config";import{db as M}from"@stacksjs/database";import{HttpError as I0}from"@stacksjs/error-handling";import{formatDate as i,User as e}from"@stacksjs/orm";import{getCurrentRequest as p$,request as b0}from"@stacksjs/router";import{Buffer as H0}from"buffer";import{createHash as m$,timingSafeEqual as k0}from"crypto";import{decrypt as L1,encrypt as c$,verifyHash as M0}from"@stacksjs/security";import{log as V1}from"@stacksjs/logging";var a="$2b$12$000000000000000000000uGByljkdFkOJRCRiYZGFOAstyLlSgTSW";import{HttpError as V$}from"@stacksjs/error-handling";var F$=5,W1=900000,B$=1e4,O$=300000;class T0{store=new Map;lastEviction=Date.now();evict(){let $=Date.now(),W=$-this.lastEviction>=O$,Z=this.store.size>=B$;if(!W&&!Z)return;this.lastEviction=$;for(let[J,Q]of this.store)if(Q.lockedUntil>0&&Q.lockedUntil<=$)this.store.delete(J);else if(Q.lockedUntil===0&&Q.attempts===0)this.store.delete(J)}get($){return this.evict(),this.store.get($)}set($,W){this.store.set($,W)}delete($){this.store.delete($)}}class Z1{prefix="auth:ratelimit:";async get($){let{cache:W}=await import("@stacksjs/cache"),Z=await W.get(`${this.prefix}${$}`);if(Z==null)return;try{return typeof Z==="string"?JSON.parse(Z):Z}catch{return}}async set($,W,Z){let{cache:J}=await import("@stacksjs/cache");await J.set(`${this.prefix}${$}`,JSON.stringify(W),Math.ceil(Z/1000))}async delete($){let{cache:W}=await import("@stacksjs/cache");await W.remove(`${this.prefix}${$}`)}}var g=new T0;class k{static useStore($){g=$}static useSharedStore(){g=new Z1}static useMemoryStore(){g=new T0}static async isRateLimited($){$=$.toLowerCase();let W=Date.now(),Z=await g.get($);if(!Z)return!1;if(Z.lockedUntil>0&&Z.lockedUntil<=W)return await g.delete($),!1;return Z.lockedUntil>0}static async recordFailedAttempt($){$=$.toLowerCase();let W=Date.now(),Z=await g.get($)||{attempts:0,lockedUntil:0};if(Z.attempts++,Z.attempts>=F$)Z.lockedUntil=W+W1,Z.attempts=0;await g.set($,Z,W1)}static async resetAttempts($){await g.delete($.toLowerCase())}static async validateAttempt($){if(await this.isRateLimited($))throw new V$(429,"Too many login attempts. Please try again later.")}}L0();var F1=Symbol.for("stacks.requestAuthState");function x(){let $=p$();if(!$)return null;let W=$[F1];if(!W)W={},$[F1]=W;return W}function V0($){return m$("sha256").update($).digest("hex")}class R{static getBearerToken(){let $=b0.bearerToken?.();if(!$){let W=b0.headers?.get?.("authorization")||b0.headers?.get?.("Authorization");if(W&&W.startsWith("Bearer "))$=W.substring(7)}return $||null}static parseToken($){let W=$.indexOf(":");if(W===-1)return null;let Z=$.substring(0,W),J=$.substring(W+1);if(!Z||!J)return null;return{plainToken:Z,encryptedId:J}}static async getClientSecret(){let $=x();if($?.clientSecret)return $.clientSecret;let W=await this.getPersonalAccessClient();if($)$.clientSecret=W.secret;return W.secret}static async encryptTokenId($){return await c$(String($))}static async decryptTokenId($){try{return await L1($)}catch{try{let W=await this.getClientSecret();return await L1($,W)}catch{return null}}}static async getPersonalAccessClient(){try{let $=await M.selectFrom("oauth_clients").where("personal_access_client","=",!0).where("revoked","=",!1).selectAll().executeTakeFirst();if(!$)throw new I0(500,"No personal access client found. Please run `./buddy auth:setup` first.");return $}catch($){if($ instanceof Error&&$.message.includes("does not exist"))throw new I0(500,"OAuth tables not found. Please run `./buddy auth:setup` first.");throw $}}static async validateClient($,W){let Z=await M.selectFrom("oauth_clients").where("id","=",$).where("revoked","=",!1).selectAll().executeTakeFirst(),J=H0.from(W);if(!Z?.secret){let X=H0.alloc(Math.max(J.length,1)),K=J.length>0?J:H0.alloc(1);return k0(X,K),!1}let Q=String(Z.secret);if(Q.startsWith("$2"))return await M0(W,Q);let G=H0.from(Q);if(G.length!==J.length)return k0(G,G),!1;return k0(G,J)}static async getTokenFromId($){let W=await M.selectFrom("oauth_access_tokens").where("id","=",$).selectAll().executeTakeFirst();if(!W)return null;let Z=W;return{id:Z.id,userId:Z.user_id,clientId:Z.oauth_client_id,name:Z.name||"auth-token",scopes:w(Z.scopes),abilities:w(Z.scopes),expiresAt:Z.expires_at?new Date(String(Z.expires_at)):null,createdAt:Z.created_at?new Date(String(Z.created_at)):new Date,updatedAt:Z.updated_at?new Date(String(Z.updated_at)):new Date,revoked:!!Z.revoked}}static async attempt($){let W=S.auth.username||"email",Z=S.auth.password||"password",J=$[W];if(!J)return!1;let Q=await k.isRateLimited(J),G=await e.where("email","=",J).first(),X=$[Z]||"",K=G?.password||a,Y=await M0(X,K);if(Q)return!1;if(Y&&G){await k.resetAttempts(J);let L=x();if(L)L.authUser=G;return!0}return await k.recordFailedAttempt(J),!1}static async validate($){let W=S.auth.username||"email",Z=S.auth.password||"password",J=$[W];if(!J)return!1;let Q=await e.where("email","=",J).first(),G=$[Z]||"",X=Q?.password||a;return await M0(G,X)&&!!Q}static async login($,W){let Z=await this.attempt($),J=x()?.authUser;if(!Z||!J)return null;let{plainTextToken:Q,refreshToken:G,expiresIn:X}=await this.createTokenForUser(J,W);return{user:J,token:Q,refreshToken:G,expiresIn:X}}static async loginUsingId($,W){let Z=await e.find($);if(!Z)return null;let J=x();if(J)J.authUser=Z;let{plainTextToken:Q,refreshToken:G,expiresIn:X}=await this.createTokenForUser(Z,W);return{user:Z,token:Q,refreshToken:G,expiresIn:X}}static async logout(){let $=this.getBearerToken();if($){let Z=await M.selectFrom("oauth_access_tokens").where("token","=",V0($)).select(["id"]).executeTakeFirst();if(Z)await M.updateTable("oauth_refresh_tokens").set({revoked:!0}).where("access_token_id","=",Number(Z.id)).execute();await this.revokeToken($)}let W=x();if(W)W.authUser=void 0,W.currentToken=void 0}static async user(){let $=x();if($?.authUser)return $.authUser;let W=this.getBearerToken();if(!W)return;let Z=await this.getUserFromToken(W);if(Z&&$)$.authUser=Z;return Z}static async check(){return await this.user()!==void 0}static async guest(){return!await this.check()}static async id(){return(await this.user())?.id}static setUser($){let W=x();if(W)W.authUser=$}static async createTokenForUser($,W){let Z=W?.name??S.auth.defaultTokenName??"auth-token",J=W?.abilities??W?.scopes??S.auth.defaultAbilities??["*"],Q=W?.expiresInMinutes!==void 0?W.expiresInMinutes*60*1000:S.auth.tokenExpiry??3600000,X=W?.expiresAt??new Date(Date.now()+Q),K=Math.max(1,Math.floor((X.getTime()-Date.now())/60000)),Y=W?.refreshExpiresInDays??Math.max(1,Math.round((S.auth.refreshTokenExpiry??2592000000)/86400000));V1.debug(`[auth] Creating token for user#${$.id}: ${Z}`);let L=await w0($.id,Z,J,{expiresInMinutes:K,withRefreshToken:W?.withRefreshToken!==!1,refreshExpiresInDays:Y}),O=L.plainTextToken;return{accessToken:{id:L.accessToken.id,userId:L.accessToken.userId,clientId:L.accessToken.clientId,name:L.accessToken.name,scopes:L.accessToken.scopes,abilities:J,expiresAt:L.accessToken.expiresAt??X,createdAt:L.accessToken.createdAt,updatedAt:L.accessToken.updatedAt,revoked:L.accessToken.revoked,plainTextToken:O},plainTextToken:O,refreshToken:L.refreshToken,expiresIn:L.expiresIn}}static async createToken($,W=S.auth.defaultTokenName||"auth-token",Z=S.auth.defaultAbilities||["*"]){let{plainTextToken:J}=await this.createTokenForUser($,{name:W,abilities:Z});return J}static async requestToken($,W,Z){if(!await this.validateClient(W,Z))throw new I0(401,"Invalid client credentials");let Q=await this.attempt($),G=x()?.authUser;if(!Q||!G)return null;return{token:await this.createToken(G,"user-auth-token")}}static async validateToken($){let W=V0($),Z=await M.selectFrom("oauth_access_tokens").where("token","=",W).selectAll().executeTakeFirst();if(!Z)return!1;if(V1.debug(`[auth] Token validated for token#${Z.id}`),Z.expires_at&&new Date(String(Z.expires_at))<new Date)return await M.deleteFrom("oauth_access_tokens").where("id","=",Z.id).execute(),!1;if(Z.revoked)return!1;if(d(Z.created_at,await s(Z.user_id)))return!1;return await M.updateTable("oauth_access_tokens").set({updated_at:i(new Date)}).where("id","=",Z.id).execute(),!0}static async getUserFromToken($){let W=V0($),Z=await M.selectFrom("oauth_access_tokens").where("token","=",W).selectAll().executeTakeFirst();if(!Z)return;if(Z.expires_at&&new Date(String(Z.expires_at))<new Date){await M.deleteFrom("oauth_access_tokens").where("id","=",Z.id).execute();return}if(Z.revoked)return;let J=x();if(J)J.currentToken=await this.getTokenFromId(Z.id)??void 0;if(await M.updateTable("oauth_access_tokens").set({updated_at:i(new Date)}).where("id","=",Z.id).execute(),!Z?.user_id)return;let Q=await e.find(Z.user_id),G=Q?.password_changed_at,X=G?new Date(String(G)):null;if(d(Z.created_at,X))return;return Q}static async currentAccessToken(){let $=x();if($?.currentToken)return $.currentToken;let W=this.getBearerToken();if(!W)return;let Z=await M.selectFrom("oauth_access_tokens").where("token","=",V0(W)).select(["id"]).executeTakeFirst();if(!Z)return;let J=await this.getTokenFromId(Number(Z.id));if(J&&$)$.currentToken=J;return J??void 0}static async tokenCan($){let W=await this.currentAccessToken();if(!W)return!1;if(W.abilities.includes("*"))return!0;return W.abilities.includes($)}static async tokenCant($){return!await this.tokenCan($)}static async tokenAbilities(){return(await this.currentAccessToken())?.abilities??[]}static async tokenCanAll($){let W=await this.currentAccessToken();if(!W)return!1;if(W.abilities.includes("*"))return!0;return $.every((Z)=>W.abilities.includes(Z))}static async tokenCanAny($){let W=await this.currentAccessToken();if(!W)return!1;if(W.abilities.includes("*"))return!0;return $.some((Z)=>W.abilities.includes(Z))}static async tokens($){let W=$??await this.id();if(!W)return[];return(await M.selectFrom("oauth_access_tokens").where("user_id","=",W).where("revoked","=",!1).selectAll().execute()).map((J)=>({id:Number(J.id),userId:Number(J.user_id),clientId:Number(J.oauth_client_id),name:String(J.name||"auth-token"),scopes:w(String(J.scopes??"")),abilities:w(String(J.scopes??"")),expiresAt:J.expires_at?new Date(String(J.expires_at)):null,createdAt:J.created_at?new Date(String(J.created_at)):new Date,updatedAt:J.updated_at?new Date(String(J.updated_at)):new Date,revoked:!!J.revoked}))}static async revokeToken($){await M.updateTable("oauth_access_tokens").set({revoked:!0,updated_at:i(new Date)}).where("token","=",V0($)).execute()}static async revokeTokenById($){await M.updateTable("oauth_access_tokens").set({revoked:!0,updated_at:i(new Date)}).where("id","=",$).execute()}static async revokeAllTokens($){let W=$??await this.id();if(!W)return;await M.updateTable("oauth_access_tokens").set({revoked:!0,updated_at:i(new Date)}).where("user_id","=",W).execute()}static async revokeOtherTokens($){let W=$??await this.id();if(!W)return;let Z=await this.currentAccessToken();if(!Z)return;await M.updateTable("oauth_access_tokens").set({revoked:!0,updated_at:i(new Date)}).where("user_id","=",W).where("id","!=",Z.id).execute()}static async pruneExpiredTokens(){let $=await M.deleteFrom("oauth_access_tokens").where("expires_at","<",i(new Date)).executeTakeFirst();return Number($?.numDeletedRows)||0}static async pruneRevokedTokens(){let $=await M.deleteFrom("oauth_access_tokens").where("revoked","=",!0).executeTakeFirst();return Number($?.numDeletedRows)||0}static async rotateToken($){let{findToken:W,revokeToken:Z}=await Promise.resolve().then(() => (L0(),K1)),J=await W($);if(!J)return null;let Q=J.expiresAt?J.expiresAt.getTime()-Date.now():S.auth.tokenExpiry??3600000,G=Math.max(1,Math.floor(Q/60000));await Z($);let X=await e.find(J.userId);if(!X)return null;return(await this.createTokenForUser(X,{name:J.name,abilities:J.scopes??["*"],expiresInMinutes:G,withRefreshToken:!1})).plainTextToken}static async findToken($){return this.getTokenFromId($)}static async once($){let W=S.auth.username||"email",Z=S.auth.password||"password",J=$[W];if(!J)return!1;let Q=await e.where("email","=",J).first(),G=$[Z]||"",X=Q?.password||a;if(await M0(G,X)&&Q){let Y=x();if(Y)Y.authUser=Q;return!0}return!1}static guard($){return this}static viaRemember(){return!1}static clearState(){let $=x();if($)$.authUser=void 0,$.currentToken=void 0,$.clientSecret=void 0}}import{generateTOTP as u$,generateTOTPSecret as l$,totpKeyUri as d$,verifyTOTP as n$}from"@stacksjs/ts-auth";function g0(){return l$()}async function gZ($){return u$({secret:$})}async function h0($,W){return n$($,{secret:W})}function B1($,W,Z){let J=$||"johndoe@example.com",Q=W||"StacksJS 2fa",G=Z||g0();return d$(J,Q,G)}import{randomBytes as i$}from"crypto";import{db as U0}from"@stacksjs/database";import{formatDate as t$}from"@stacksjs/orm";import{err as o$,HttpError as a$,ok as r$}from"@stacksjs/error-handling";import{makeHash as s$}from"@stacksjs/security";async function dZ(){if((await U0.selectFrom("oauth_clients").where("personal_access_client","=",!0).where("revoked","=",!1).select(["id"]).executeTakeFirst())?.id)return o$({code:"already-exists",message:"A personal access client already exists. Revoke the existing client (`./buddy auth:revoke-client`) before creating a new one."});let W=i$(40).toString("hex"),Z=await s$(W,{algorithm:"bcrypt"});if(await U0.insertInto("oauth_clients").values({name:"Personal Access Client",secret:Z,provider:"local",redirect:"http://localhost",personal_access_client:!0,password_client:!1,revoked:!1,created_at:t$(new Date)}).execute(),!(await U0.selectFrom("oauth_clients").where("secret","=",Z).select(["id"]).executeTakeFirst())?.id)throw new a$(500,"Failed to create personal access client");return r$(W)}async function e$($){let W=$.bearerToken?.();if(!W){let Q=$.headers?.get?.("authorization")||$.headers?.get?.("Authorization");if(Q&&Q.startsWith("Bearer "))W=Q.substring(7)}if(!W){let Q=Error("No authentication token provided.");throw Q.statusCode=401,Q}let Z=await R.getUserFromToken(W);if(!Z){let Q=Error("Invalid or expired authentication token.");throw Q.statusCode=401,Q}R.setUser(Z),$._authenticatedUser=Z;let J=await R.currentAccessToken();$._currentAccessToken=J}var tZ={name:"auth",handle:e$};import{Buffer as O1}from"buffer";import{db as p}from"@stacksjs/database";import{generateRegistrationOptions as G2,generateAuthenticationOptions as X2,verifyRegistrationResponse as Y2,verifyAuthenticationResponse as K2,startRegistration as L2,startAuthentication as V2,browserSupportsWebAuthn as F2,browserSupportsWebAuthnAutofill as B2,platformAuthenticatorIsAvailable as O2}from"@stacksjs/ts-auth";async function sZ($){return await p.selectFrom("passkeys").selectAll().where("user_id","=",$).execute()}async function $W($,W){return await p.selectFrom("passkeys").selectAll().where("id","=",W).where("user_id","=",$).executeTakeFirst()}async function eZ($,W,Z){let J=await $W($,W);if(!J)return!1;let Q=Number(J.counter??0);if(Z!==0&&Z<=Q)return!1;return await p.updateTable("passkeys").set({counter:Z,last_used_at:_1()}).where("id","=",W).where("user_id","=",$).execute(),!0}async function $2($,W){let Z=W.registrationInfo?.credential.id,J=W.registrationInfo?.credential.publicKey;if(!Z)throw Error("[auth/passkey] WebAuthn registration response is missing credential.id");if(!J)throw Error("[auth/passkey] WebAuthn registration response is missing credential.publicKey");let Q={id:Z,cred_public_key:JSON.stringify(J),user_id:$.id,webauthn_user_id:$.email||"",counter:W.registrationInfo?.credential.counter||0,credential_type:W.registrationInfo?.credentialType||"",device_type:W.registrationInfo?.credentialDeviceType||"",backup_eligible:!1,backup_status:W.registrationInfo?.credentialBackedUp||!1,transports:JSON.stringify(["internal"]),last_used_at:_1()};await p.insertInto("passkeys").values(Q).executeTakeFirstOrThrow()}function _1(){let $=new Date,W=(Y)=>String(Y).padStart(2,"0"),Z=$.getFullYear(),J=W($.getMonth()+1),Q=W($.getDate()),G=W($.getHours()),X=W($.getMinutes()),K=W($.getSeconds());return`${Z}-${J}-${Q} ${G}:${X}:${K}`}var WW=300;async function W2($,W,Z,J=WW){let Q=new Date(Date.now()+J*1000).toISOString(),G=typeof W==="string"?W:O1.from(W).toString("base64url");await p.deleteFrom("webauthn_challenges").where("user_id","=",$).where("purpose","=",Z).execute(),await p.insertInto("webauthn_challenges").values({user_id:$,challenge:G,purpose:Z,expires_at:Q}).execute()}async function Z2($,W){let Z=await p.selectFrom("webauthn_challenges").where("user_id","=",$).where("purpose","=",W).selectAll().executeTakeFirst();if(!Z)return null;await p.deleteFrom("webauthn_challenges").where("user_id","=",$).where("purpose","=",W).execute();let J=Z.expires_at?new Date(String(Z.expires_at)).getTime():0;if(Date.now()>J)return null;return O1.from(String(Z.challenge),"base64url")}import{randomBytes as VW}from"crypto";import{config as m}from"@stacksjs/config";import{db as t}from"@stacksjs/database";import{mail as C0,template as M1}from"@stacksjs/email";import{log as FW}from"@stacksjs/logging";import{formatDate as BW}from"@stacksjs/orm";import{makeHash as D1,verifyHash as j1}from"@stacksjs/security";import{HttpError as p0}from"@stacksjs/error-handling";import{log as q0}from"@stacksjs/logging";import{User as z1}from"@stacksjs/orm";import{verifyHash as ZW}from"@stacksjs/security";import{db as f}from"@stacksjs/database";import{getCurrentRequest as JW}from"@stacksjs/router";function QW(){let $=crypto.getRandomValues(new Uint8Array(32));return Array.from($,(W)=>W.toString(16).padStart(2,"0")).join("")}function GW($){if($)return{ip:$.ip??null,userAgent:$.userAgent??null};let W=JW();if(!W)return{ip:null,userAgent:null};let Z=W.headers,J=Z?.get?.("x-forwarded-for")||Z?.get?.("X-Forwarded-For")||"",Q=Z?.get?.("x-real-ip")||Z?.get?.("X-Real-IP")||"",G=(J?J.split(",")[0].trim():"")||Q||null,X=Z?.get?.("user-agent")||Z?.get?.("User-Agent")||null;return{ip:G,userAgent:X}}async function XW($,W,Z){let J=($||"").toLowerCase(),Q=await k.isRateLimited(J),G=await z1.where("email",$).first(),X=G?.password||a,K=await ZW(W,X);if(Q)throw new p0(429,"Too many login attempts. Please try again later.");if(!K||!G)throw await k.recordFailedAttempt(J),new p0(401,"Invalid credentials");await k.resetAttempts(J);let Y=QW(),L=new Date(Date.now()+86400000),{ip:O,userAgent:_}=GW(Z);q0.debug(`[auth] Session created for user#${G.id}`);try{await f.insertInto("sessions").values({id:Y,user_id:G.id,ip_address:O,user_agent:_,payload:"{}",last_activity:Math.floor(Date.now()/1000),expires_at:L.toISOString()}).execute()}catch(E){throw q0.error(`[auth] Session persistence failed for user#${G.id}: ${E.message}`),new p0(500,"Session could not be created. Ensure the `sessions` table exists (run `./buddy migrate`).")}return{user:G,sessionId:Y}}async function YW($){q0.debug("[auth] Session destroyed");try{await f.deleteFrom("sessions").where("id","=",$).execute()}catch(W){q0.debug(`[auth] Session destroy failed: ${W.message}`)}}async function m0($){try{await f.deleteFrom("sessions").where("user_id","=",$).execute()}catch(W){let Z=W instanceof Error?W.message:String(W);if(Z.includes("sessions")&&/no such table|does not exist|doesn't exist/i.test(Z))return;throw W}}async function c0($){try{let W=await f.selectFrom("sessions").where("id","=",$).selectAll().executeTakeFirst();if(!W)return;let Z=W.expires_at?new Date(String(W.expires_at)).getTime():0;if(Date.now()>Z){await f.deleteFrom("sessions").where("id","=",$).execute();return}return await z1.find(W.user_id)}catch{return}}async function KW($){try{let W=await f.selectFrom("sessions").where("id","=",$).selectAll().executeTakeFirst();if(!W)return!1;let Z=W.expires_at?new Date(String(W.expires_at)).getTime():0;if(Date.now()>Z)return await f.deleteFrom("sessions").where("id","=",$).execute(),!1;return!0}catch{return!1}}async function LW($,W=86400000){try{let Z=await f.selectFrom("sessions").where("id","=",$).selectAll().executeTakeFirst();if(!Z)return!1;let J=Z.expires_at?new Date(String(Z.expires_at)).getTime():0;if(Date.now()>J)return await f.deleteFrom("sessions").where("id","=",$).execute(),!1;let Q=new Date(Date.now()+W);return await f.updateTable("sessions").set({expires_at:Q.toISOString(),last_activity:Math.floor(Date.now()/1000)}).where("id","=",$).execute(),!0}catch{return!1}}var C2={login:XW,logout:YW,destroyAll:m0,user:c0,check:KW,refresh:LW};L0();function u0(){return m.auth.passwordReset?.expire??60}function H1($){let W=$.expires_at;if(typeof W==="string"||W instanceof Date)return new Date(W).getTime()>Date.now();let Z=$.created_at;if(typeof Z==="string"||Z instanceof Date){let J=u0();return new Date(Z).getTime()+J*60000>Date.now()}return!1}async function OW($){let W=m.app.name||"Stacks",Z=m.app.supportEmail||m.email?.from?.address||"",J=new Date().toLocaleString("en-US",{dateStyle:"full",timeStyle:"short"});try{let{html:Q,text:G}=await M1("password-changed",{subject:`Your ${W} password has been changed`,variables:{changedAt:J,supportEmail:Z}});if(!Q&&!G){await C0.send({to:$,subject:`Your ${W} password has been changed`,text:`Your ${W} password was changed on ${J}.${Z?` If this wasn't you, contact ${Z}.`:""}`});return}await C0.send({to:$,subject:`Your ${W} password has been changed`,text:G,html:Q})}catch(Q){console.error("[PasswordReset] Failed to send password changed notification:",Q)}}function w2($){function W(){return VW(32).toString("hex")}async function Z(){let X=W(),K=await D1(X,{algorithm:"bcrypt"}),Y=u0(),L=new Date(Date.now()+Y*60000).toISOString();return await t.deleteFrom("password_resets").where("email","=",$).execute(),await t.insertInto("password_resets").values({email:$,token:K,expires_at:L}).executeTakeFirst(),X}async function J(){if(!await t.selectFrom("users").where("email","=",$).selectAll().executeTakeFirst())return;let K=await Z(),Y=u0(),L=m.app.name||"Stacks",O=m.app.url?`https://${m.app.url}`:`http://localhost:${process.env.PORT||"3000"}`,E=(m.auth.passwordReset?.url??"/password/reset/{token}?email={email}").replace("{token}",K).replace("{email}",encodeURIComponent($)),F=/^https?:\/\//.test(E)?E:`${O}${E.startsWith("/")?"":"/"}${E}`;try{let{html:H,text:P}=await M1("password-reset",{subject:`Reset Your ${L} Password`,variables:{resetUrl:F,expireMinutes:Y}});if(!H&&!P)throw Error("password-reset template missing or rendered empty");await C0.send({to:$,subject:`Reset Your ${L} Password`,text:P,html:H})}catch(H){let P=H instanceof Error?H.message:String(H);console.warn(`[PasswordReset] template render failed, sending plain-text fallback: ${P}`),await C0.send({to:$,subject:`Reset Your ${L} Password`,text:`Reset your password by visiting: ${F}
161
+ `,[$])}function w($){if(!$)return[];if(Array.isArray($))return $;try{let W=JSON.parse($);return Array.isArray(W)?W:[]}catch{return[]}}function w0($){return{id:$.id,name:$.name,secret:$.secret,provider:$.provider,redirect:$.redirect,personalAccessClient:Boolean($.personal_access_client),passwordClient:Boolean($.password_client),revoked:Boolean($.revoked),createdAt:$.created_at?new Date($.created_at):new Date,updatedAt:$.updated_at?new Date($.updated_at):null}}var L$,o0,o,FZ,M,P,X0,F$;var Y0=n0(()=>{L$=Y$.DB_CONNECTION||"sqlite",o0=K$(L$),{isPostgres:o,isMysql:FZ,now:M,boolTrue:P,boolFalse:X0}=o0;F$=l});var S1={};d0(S1,{policy:()=>F0,none:()=>M1,inspect:()=>e,hasPolicy:()=>C1,has:()=>q1,getPolicyFor:()=>U1,flush:()=>v1,denies:()=>H1,define:()=>_1,default:()=>LW,cannot:()=>P0,can:()=>C0,before:()=>z1,authorize:()=>E0,any:()=>B0,allows:()=>j1,all:()=>v0,after:()=>D1,abilities:()=>P1,Gate:()=>E1,AuthorizationResponse:()=>U,AuthorizationException:()=>V0});class U{isAllowed;message;code;constructor($,W,Z){this.isAllowed=$,this.message=W,this.code=Z}static allow($){return new U(!0,$)}static deny($,W){return new U(!1,$||"This action is unauthorized.",W)}allowed(){return this.isAllowed}denied(){return!this.isAllowed}authorize(){if(!this.isAllowed)throw new V0(this.message||"This action is unauthorized.",this.code)}}function _1($,W){q.gates.set($,W)}function F0($,W){let Z=typeof $==="string"?$:$.name;q.policies.set(Z,W)}function z1($){q.beforeCallbacks.push($)}function D1($){q.afterCallbacks.push($)}async function j1($,W,...Z){return $0($,W,...Z)}async function H1($,W,...Z){return!await $0($,W,...Z)}async function C0($,W,...Z){return $0($,W,...Z)}async function P0($,W,...Z){return!await $0($,W,...Z)}async function B0($,W,...Z){for(let J of $)if(await $0(J,W,...Z))return!0;return!1}async function v0($,W,...Z){for(let J of $)if(!await $0(J,W,...Z))return!1;return!0}async function M1($,W,...Z){return!await B0($,W,...Z)}async function E0($,W,...Z){let J=await e($,W,...Z);if(!J.isAllowed)throw new V0(J.message,J.code);return J}async function e($,W,...Z){for(let G of q.beforeCallbacks){let X=await G(W,$,Z);if(X===!0)return U.allow();if(X===!1)return U.deny()}let J=Z[0];if(J&&typeof J==="object"){let G=J.constructor?.name,X=q.policies.get(G);if(X){let K=new X;if(K.before){let L=await K.before(W,$);if(L===!0)return U.allow();if(L===!1)return U.deny()}let Y=K[$];if(Y){let L=await Y.call(K,W,...Z);return O1(L??!1)}}}let Q=q.gates.get($);if(Q){let G=await Q(W,...Z),X=O1(G);for(let K of q.afterCallbacks){let Y=await K(W,$,X.isAllowed,Z);if(typeof Y==="boolean")return Y?U.allow():U.deny()}return X}return U.deny(`No gate or policy defined for ability: ${$}`)}async function $0($,W,...Z){return(await e($,W,...Z)).isAllowed}function O1($){if($ instanceof U)return $;if(typeof $!=="boolean")throw TypeError(`[gate] Policy must return boolean or AuthorizationResponse; got ${typeof $}. If you returned a model/value by mistake, return \`true\`/\`false\` instead.`);return $?U.allow():U.deny()}function U1($){if(!$||typeof $!=="object")return null;let W=$.constructor?.name,Z=q.policies.get(W);if(Z)return new Z;return null}function q1($){return q.gates.has($)}function C1($){let W=typeof $==="string"?$:$.name;return q.policies.has(W)}function P1(){return Array.from(q.gates.keys())}function v1(){q.gates.clear(),q.policies.clear(),q.beforeCallbacks=[],q.afterCallbacks=[]}var V0,q,E1,LW;var W0=n0(()=>{V0=class V0 extends Error{code;status;constructor($="This action is unauthorized.",W,Z=403){super($);this.code=W;this.status=Z;this.name="AuthorizationException"}};q={gates:new Map,policies:new Map,beforeCallbacks:[],afterCallbacks:[]};E1={define:_1,policy:F0,before:z1,after:D1,allows:j1,denies:H1,can:C0,cannot:P0,any:B0,all:v0,none:M1,authorize:E0,inspect:e,has:q1,hasPolicy:C1,abilities:P1,getPolicyFor:U1,flush:v1,AuthorizationResponse:U,AuthorizationException:V0},LW=E1});import{config as v}from"@stacksjs/config";import{db as H}from"@stacksjs/database";import{HttpError as T0}from"@stacksjs/error-handling";import{formatDate as d,User as r}from"@stacksjs/orm";import{getCurrentRequest as y$,request as f0}from"@stacksjs/router";import{Buffer as D0}from"buffer";import{createHash as N$,timingSafeEqual as I0}from"crypto";import{decrypt as W1,encrypt as w$,verifyHash as j0}from"@stacksjs/security";import{log as Z1}from"@stacksjs/logging";var t="$2b$12$000000000000000000000uGByljkdFkOJRCRiYZGFOAstyLlSgTSW";import{HttpError as $$}from"@stacksjs/error-handling";var W$=5,i0=900000,Z$=1e4,J$=300000;class y0{store=new Map;lastEviction=Date.now();evict(){let $=Date.now(),W=$-this.lastEviction>=J$,Z=this.store.size>=Z$;if(!W&&!Z)return;this.lastEviction=$;for(let[J,Q]of this.store)if(Q.lockedUntil>0&&Q.lockedUntil<=$)this.store.delete(J);else if(Q.lockedUntil===0&&Q.attempts===0)this.store.delete(J)}get($){return this.evict(),this.store.get($)}set($,W){this.store.set($,W)}delete($){this.store.delete($)}}class t0{prefix="auth:ratelimit:";async get($){let{cache:W}=await import("@stacksjs/cache"),Z=await W.get(`${this.prefix}${$}`);if(Z==null)return;try{return typeof Z==="string"?JSON.parse(Z):Z}catch{return}}async set($,W,Z){let{cache:J}=await import("@stacksjs/cache");await J.set(`${this.prefix}${$}`,JSON.stringify(W),Math.ceil(Z/1000))}async delete($){let{cache:W}=await import("@stacksjs/cache");await W.remove(`${this.prefix}${$}`)}}var I=new y0;class f{static useStore($){I=$}static useSharedStore(){I=new t0}static useMemoryStore(){I=new y0}static async isRateLimited($){$=$.toLowerCase();let W=Date.now(),Z=await I.get($);if(!Z)return!1;if(Z.lockedUntil>0&&Z.lockedUntil<=W)return await I.delete($),!1;return Z.lockedUntil>0}static async recordFailedAttempt($){$=$.toLowerCase();let W=Date.now(),Z=await I.get($)||{attempts:0,lockedUntil:0};if(Z.attempts++,Z.attempts>=W$)Z.lockedUntil=W+i0,Z.attempts=0;await I.set($,Z,i0)}static async resetAttempts($){await I.delete($.toLowerCase())}static async validateAttempt($){if(await this.isRateLimited($))throw new $$(429,"Too many login attempts. Please try again later.")}}Y0();var J1=Symbol.for("stacks.requestAuthState");function S(){let $=y$();if(!$)return null;let W=$[J1];if(!W)W={},$[J1]=W;return W}function K0($){return N$("sha256").update($).digest("hex")}class x{static getBearerToken(){let $=f0.bearerToken?.();if(!$){let W=f0.headers?.get?.("authorization")||f0.headers?.get?.("Authorization");if(W&&W.startsWith("Bearer "))$=W.substring(7)}return $||null}static parseToken($){let W=$.indexOf(":");if(W===-1)return null;let Z=$.substring(0,W),J=$.substring(W+1);if(!Z||!J)return null;return{plainToken:Z,encryptedId:J}}static async getClientSecret(){let $=S();if($?.clientSecret)return $.clientSecret;let W=await this.getPersonalAccessClient();if($)$.clientSecret=W.secret;return W.secret}static async encryptTokenId($){return await w$(String($))}static async decryptTokenId($){try{return await W1($)}catch{try{let W=await this.getClientSecret();return await W1($,W)}catch{return null}}}static async getPersonalAccessClient(){try{let $=await H.selectFrom("oauth_clients").where("personal_access_client","=",!0).where("revoked","=",!1).selectAll().executeTakeFirst();if(!$)throw new T0(500,"No personal access client found. Please run `./buddy auth:setup` first.");return $}catch($){if($ instanceof Error&&$.message.includes("does not exist"))throw new T0(500,"OAuth tables not found. Please run `./buddy auth:setup` first.");throw $}}static async validateClient($,W){let Z=await H.selectFrom("oauth_clients").where("id","=",$).where("revoked","=",!1).selectAll().executeTakeFirst(),J=D0.from(W);if(!Z?.secret){let X=D0.alloc(Math.max(J.length,1)),K=J.length>0?J:D0.alloc(1);return I0(X,K),!1}let Q=String(Z.secret);if(Q.startsWith("$2"))return await j0(W,Q);let G=D0.from(Q);if(G.length!==J.length)return I0(G,G),!1;return I0(G,J)}static async getTokenFromId($){let W=await H.selectFrom("oauth_access_tokens").where("id","=",$).selectAll().executeTakeFirst();if(!W)return null;let Z=W;return{id:Z.id,userId:Z.user_id,clientId:Z.oauth_client_id,name:Z.name||"auth-token",scopes:w(Z.scopes),abilities:w(Z.scopes),expiresAt:Z.expires_at?new Date(String(Z.expires_at)):null,createdAt:Z.created_at?new Date(String(Z.created_at)):new Date,updatedAt:Z.updated_at?new Date(String(Z.updated_at)):new Date,revoked:!!Z.revoked}}static async attempt($){let W=v.auth.username||"email",Z=v.auth.password||"password",J=$[W];if(!J)return!1;let Q=await f.isRateLimited(J),G=await r.where("email","=",J).first(),X=$[Z]||"",K=G?.password||t,Y=await j0(X,K);if(Q)return!1;if(Y&&G){await f.resetAttempts(J);let L=S();if(L)L.authUser=G;return!0}return await f.recordFailedAttempt(J),!1}static async validate($){let W=v.auth.username||"email",Z=v.auth.password||"password",J=$[W];if(!J)return!1;let Q=await r.where("email","=",J).first(),G=$[Z]||"",X=Q?.password||t;return await j0(G,X)&&!!Q}static async login($,W){let Z=await this.attempt($),J=S()?.authUser;if(!Z||!J)return null;let{plainTextToken:Q,refreshToken:G,expiresIn:X}=await this.createTokenForUser(J,W);return{user:J,token:Q,refreshToken:G,expiresIn:X}}static async loginUsingId($,W){let Z=await r.find($);if(!Z)return null;let J=S();if(J)J.authUser=Z;let{plainTextToken:Q,refreshToken:G,expiresIn:X}=await this.createTokenForUser(Z,W);return{user:Z,token:Q,refreshToken:G,expiresIn:X}}static async logout(){let $=this.getBearerToken();if($){let Z=await H.selectFrom("oauth_access_tokens").where("token","=",K0($)).select(["id"]).executeTakeFirst();if(Z)await H.updateTable("oauth_refresh_tokens").set({revoked:!0}).where("access_token_id","=",Number(Z.id)).execute();await this.revokeToken($)}let W=S();if(W)W.authUser=void 0,W.currentToken=void 0}static async user(){let $=S();if($?.authUser)return $.authUser;let W=this.getBearerToken();if(!W)return;let Z=await this.getUserFromToken(W);if(Z&&$)$.authUser=Z;return Z}static async check(){return await this.user()!==void 0}static async guest(){return!await this.check()}static async id(){return(await this.user())?.id}static setUser($){let W=S();if(W)W.authUser=$}static async createTokenForUser($,W){let Z=W?.name??v.auth.defaultTokenName??"auth-token",J=W?.abilities??W?.scopes??v.auth.defaultAbilities??["*"],Q=W?.expiresInMinutes!==void 0?W.expiresInMinutes*60*1000:v.auth.tokenExpiry??3600000,X=W?.expiresAt??new Date(Date.now()+Q),K=Math.max(1,Math.floor((X.getTime()-Date.now())/60000)),Y=W?.refreshExpiresInDays??Math.max(1,Math.round((v.auth.refreshTokenExpiry??2592000000)/86400000));Z1.debug(`[auth] Creating token for user#${$.id}: ${Z}`);let L=await N0($.id,Z,J,{expiresInMinutes:K,withRefreshToken:W?.withRefreshToken!==!1,refreshExpiresInDays:Y}),O=L.plainTextToken;return{accessToken:{id:L.accessToken.id,userId:L.accessToken.userId,clientId:L.accessToken.clientId,name:L.accessToken.name,scopes:L.accessToken.scopes,abilities:J,expiresAt:L.accessToken.expiresAt??X,createdAt:L.accessToken.createdAt,updatedAt:L.accessToken.updatedAt,revoked:L.accessToken.revoked,plainTextToken:O},plainTextToken:O,refreshToken:L.refreshToken,expiresIn:L.expiresIn}}static async createToken($,W=v.auth.defaultTokenName||"auth-token",Z=v.auth.defaultAbilities||["*"]){let{plainTextToken:J}=await this.createTokenForUser($,{name:W,abilities:Z});return J}static async requestToken($,W,Z){if(!await this.validateClient(W,Z))throw new T0(401,"Invalid client credentials");let Q=await this.attempt($),G=S()?.authUser;if(!Q||!G)return null;return{token:await this.createToken(G,"user-auth-token")}}static async validateToken($){let W=K0($),Z=await H.selectFrom("oauth_access_tokens").where("token","=",W).selectAll().executeTakeFirst();if(!Z)return!1;if(Z1.debug(`[auth] Token validated for token#${Z.id}`),Z.expires_at&&new Date(String(Z.expires_at))<new Date)return await H.deleteFrom("oauth_access_tokens").where("id","=",Z.id).execute(),!1;if(Z.revoked)return!1;if(u(Z.created_at,await a(Z.user_id)))return!1;return await H.updateTable("oauth_access_tokens").set({updated_at:d(new Date)}).where("id","=",Z.id).execute(),!0}static async getUserFromToken($){let W=K0($),Z=await H.selectFrom("oauth_access_tokens").where("token","=",W).selectAll().executeTakeFirst();if(!Z)return;if(Z.expires_at&&new Date(String(Z.expires_at))<new Date){await H.deleteFrom("oauth_access_tokens").where("id","=",Z.id).execute();return}if(Z.revoked)return;let J=S();if(J)J.currentToken=await this.getTokenFromId(Z.id)??void 0;if(await H.updateTable("oauth_access_tokens").set({updated_at:d(new Date)}).where("id","=",Z.id).execute(),!Z?.user_id)return;let Q=await r.find(Z.user_id),G=Q?.password_changed_at,X=G?new Date(String(G)):null;if(u(Z.created_at,X))return;return Q}static async currentAccessToken(){let $=S();if($?.currentToken)return $.currentToken;let W=this.getBearerToken();if(!W)return;let Z=await H.selectFrom("oauth_access_tokens").where("token","=",K0(W)).select(["id"]).executeTakeFirst();if(!Z)return;let J=await this.getTokenFromId(Number(Z.id));if(J&&$)$.currentToken=J;return J??void 0}static async tokenCan($){let W=await this.currentAccessToken();if(!W)return!1;if(W.abilities.includes("*"))return!0;return W.abilities.includes($)}static async tokenCant($){return!await this.tokenCan($)}static async tokenAbilities(){return(await this.currentAccessToken())?.abilities??[]}static async tokenCanAll($){let W=await this.currentAccessToken();if(!W)return!1;if(W.abilities.includes("*"))return!0;return $.every((Z)=>W.abilities.includes(Z))}static async tokenCanAny($){let W=await this.currentAccessToken();if(!W)return!1;if(W.abilities.includes("*"))return!0;return $.some((Z)=>W.abilities.includes(Z))}static async tokens($){let W=$??await this.id();if(!W)return[];return(await H.selectFrom("oauth_access_tokens").where("user_id","=",W).where("revoked","=",!1).selectAll().execute()).map((J)=>({id:Number(J.id),userId:Number(J.user_id),clientId:Number(J.oauth_client_id),name:String(J.name||"auth-token"),scopes:w(String(J.scopes??"")),abilities:w(String(J.scopes??"")),expiresAt:J.expires_at?new Date(String(J.expires_at)):null,createdAt:J.created_at?new Date(String(J.created_at)):new Date,updatedAt:J.updated_at?new Date(String(J.updated_at)):new Date,revoked:!!J.revoked}))}static async revokeToken($){await H.updateTable("oauth_access_tokens").set({revoked:!0,updated_at:d(new Date)}).where("token","=",K0($)).execute()}static async revokeTokenById($){await H.updateTable("oauth_access_tokens").set({revoked:!0,updated_at:d(new Date)}).where("id","=",$).execute()}static async revokeAllTokens($){let W=$??await this.id();if(!W)return;await H.updateTable("oauth_access_tokens").set({revoked:!0,updated_at:d(new Date)}).where("user_id","=",W).execute()}static async revokeOtherTokens($){let W=$??await this.id();if(!W)return;let Z=await this.currentAccessToken();if(!Z)return;await H.updateTable("oauth_access_tokens").set({revoked:!0,updated_at:d(new Date)}).where("user_id","=",W).where("id","!=",Z.id).execute()}static async pruneExpiredTokens(){let $=await H.deleteFrom("oauth_access_tokens").where("expires_at","<",d(new Date)).executeTakeFirst();return Number($?.numDeletedRows)||0}static async pruneRevokedTokens(){let $=await H.deleteFrom("oauth_access_tokens").where("revoked","=",!0).executeTakeFirst();return Number($?.numDeletedRows)||0}static async rotateToken($){let{findToken:W,revokeToken:Z}=await Promise.resolve().then(() => (Y0(),$1)),J=await W($);if(!J)return null;let Q=J.expiresAt?J.expiresAt.getTime()-Date.now():v.auth.tokenExpiry??3600000,G=Math.max(1,Math.floor(Q/60000));await Z($);let X=await r.find(J.userId);if(!X)return null;return(await this.createTokenForUser(X,{name:J.name,abilities:J.scopes??["*"],expiresInMinutes:G,withRefreshToken:!1})).plainTextToken}static async findToken($){return this.getTokenFromId($)}static async once($){let W=v.auth.username||"email",Z=v.auth.password||"password",J=$[W];if(!J)return!1;let Q=await r.where("email","=",J).first(),G=$[Z]||"",X=Q?.password||t;if(await j0(G,X)&&Q){let Y=S();if(Y)Y.authUser=Q;return!0}return!1}static guard($){return this}static viaRemember(){return!1}static clearState(){let $=S();if($)$.authUser=void 0,$.currentToken=void 0,$.clientSecret=void 0}}import{generateTOTP as T$,generateTOTPSecret as f$,totpKeyUri as I$,verifyTOTP as b$}from"@stacksjs/ts-auth";function b0(){return f$()}async function xZ($){return T$({secret:$})}async function k0($,W){return b$($,{secret:W})}function Q1($,W,Z){let J=$||"johndoe@example.com",Q=W||"StacksJS 2fa",G=Z||b0();return I$(J,Q,G)}import{randomBytes as k$}from"crypto";import{db as H0}from"@stacksjs/database";import{formatDate as g$}from"@stacksjs/orm";import{err as h$,HttpError as p$,ok as m$}from"@stacksjs/error-handling";import{makeHash as c$}from"@stacksjs/security";async function fZ(){if((await H0.selectFrom("oauth_clients").where("personal_access_client","=",!0).where("revoked","=",!1).select(["id"]).executeTakeFirst())?.id)return h$({code:"already-exists",message:"A personal access client already exists. Revoke the existing client (`./buddy auth:revoke-client`) before creating a new one."});let W=k$(40).toString("hex"),Z=await c$(W,{algorithm:"bcrypt"});if(await H0.insertInto("oauth_clients").values({name:"Personal Access Client",secret:Z,provider:"local",redirect:"http://localhost",personal_access_client:!0,password_client:!1,revoked:!1,created_at:g$(new Date)}).execute(),!(await H0.selectFrom("oauth_clients").where("secret","=",Z).select(["id"]).executeTakeFirst())?.id)throw new p$(500,"Failed to create personal access client");return m$(W)}async function u$($){let W=$.bearerToken?.();if(!W){let Q=$.headers?.get?.("authorization")||$.headers?.get?.("Authorization");if(Q&&Q.startsWith("Bearer "))W=Q.substring(7)}if(!W){let Q=Error("No authentication token provided.");throw Q.statusCode=401,Q}let Z=await x.getUserFromToken(W);if(!Z){let Q=Error("Invalid or expired authentication token.");throw Q.statusCode=401,Q}x.setUser(Z),$._authenticatedUser=Z;let J=await x.currentAccessToken();$._currentAccessToken=J}var kZ={name:"auth",handle:u$};import{Buffer as G1}from"buffer";import{db as k}from"@stacksjs/database";import{generateRegistrationOptions as tZ,generateAuthenticationOptions as oZ,verifyRegistrationResponse as aZ,verifyAuthenticationResponse as rZ,startRegistration as sZ,startAuthentication as eZ,browserSupportsWebAuthn as $2,browserSupportsWebAuthnAutofill as W2,platformAuthenticatorIsAvailable as Z2}from"@stacksjs/ts-auth";async function mZ($){return await k.selectFrom("passkeys").selectAll().where("user_id","=",$).execute()}async function l$($,W){return await k.selectFrom("passkeys").selectAll().where("id","=",W).where("user_id","=",$).executeTakeFirst()}async function cZ($,W,Z){let J=await l$($,W);if(!J)return!1;let Q=Number(J.counter??0);if(Z!==0&&Z<=Q)return!1;return await k.updateTable("passkeys").set({counter:Z,last_used_at:X1()}).where("id","=",W).where("user_id","=",$).execute(),!0}async function uZ($,W){let Z=W.registrationInfo?.credential.id,J=W.registrationInfo?.credential.publicKey;if(!Z)throw Error("[auth/passkey] WebAuthn registration response is missing credential.id");if(!J)throw Error("[auth/passkey] WebAuthn registration response is missing credential.publicKey");let Q={id:Z,cred_public_key:JSON.stringify(J),user_id:$.id,webauthn_user_id:$.email||"",counter:W.registrationInfo?.credential.counter||0,credential_type:W.registrationInfo?.credentialType||"",device_type:W.registrationInfo?.credentialDeviceType||"",backup_eligible:!1,backup_status:W.registrationInfo?.credentialBackedUp||!1,transports:JSON.stringify(["internal"]),last_used_at:X1()};await k.insertInto("passkeys").values(Q).executeTakeFirstOrThrow()}function X1(){let $=new Date,W=(Y)=>String(Y).padStart(2,"0"),Z=$.getFullYear(),J=W($.getMonth()+1),Q=W($.getDate()),G=W($.getHours()),X=W($.getMinutes()),K=W($.getSeconds());return`${Z}-${J}-${Q} ${G}:${X}:${K}`}var d$=300;async function lZ($,W,Z,J=d$){let Q=new Date(Date.now()+J*1000).toISOString(),G=typeof W==="string"?W:G1.from(W).toString("base64url");await k.deleteFrom("webauthn_challenges").where("user_id","=",$).where("purpose","=",Z).execute(),await k.insertInto("webauthn_challenges").values({user_id:$,challenge:G,purpose:Z,expires_at:Q}).execute()}async function dZ($,W){let Z=await k.selectFrom("webauthn_challenges").where("user_id","=",$).where("purpose","=",W).selectAll().executeTakeFirst();if(!Z)return null;await k.deleteFrom("webauthn_challenges").where("user_id","=",$).where("purpose","=",W).execute();let J=Z.expires_at?new Date(String(Z.expires_at)).getTime():0;if(Date.now()>J)return null;return G1.from(String(Z.challenge),"base64url")}import{randomBytes as $W}from"crypto";import{config as g}from"@stacksjs/config";import{db as n}from"@stacksjs/database";import{mail as U0,template as F1}from"@stacksjs/email";import{log as WW}from"@stacksjs/logging";import{formatDate as ZW}from"@stacksjs/orm";import{makeHash as K1,verifyHash as L1}from"@stacksjs/security";import{HttpError as g0}from"@stacksjs/error-handling";import{log as M0}from"@stacksjs/logging";import{User as Y1}from"@stacksjs/orm";import{verifyHash as n$}from"@stacksjs/security";import{db as T}from"@stacksjs/database";import{getCurrentRequest as i$}from"@stacksjs/router";function t$(){let $=crypto.getRandomValues(new Uint8Array(32));return Array.from($,(W)=>W.toString(16).padStart(2,"0")).join("")}function o$($){if($)return{ip:$.ip??null,userAgent:$.userAgent??null};let W=i$();if(!W)return{ip:null,userAgent:null};let Z=W.headers,J=Z?.get?.("x-forwarded-for")||Z?.get?.("X-Forwarded-For")||"",Q=Z?.get?.("x-real-ip")||Z?.get?.("X-Real-IP")||"",G=(J?J.split(",")[0].trim():"")||Q||null,X=Z?.get?.("user-agent")||Z?.get?.("User-Agent")||null;return{ip:G,userAgent:X}}async function a$($,W,Z){let J=($||"").toLowerCase(),Q=await f.isRateLimited(J),G=await Y1.where("email",$).first(),X=G?.password||t,K=await n$(W,X);if(Q)throw new g0(429,"Too many login attempts. Please try again later.");if(!K||!G)throw await f.recordFailedAttempt(J),new g0(401,"Invalid credentials");await f.resetAttempts(J);let Y=t$(),L=new Date(Date.now()+86400000),{ip:O,userAgent:_}=o$(Z);M0.debug(`[auth] Session created for user#${G.id}`);try{await T.insertInto("sessions").values({id:Y,user_id:G.id,ip_address:O,user_agent:_,payload:"{}",last_activity:Math.floor(Date.now()/1000),expires_at:L.toISOString()}).execute()}catch(E){throw M0.error(`[auth] Session persistence failed for user#${G.id}: ${E.message}`),new g0(500,"Session could not be created. Ensure the `sessions` table exists (run `./buddy migrate`).")}return{user:G,sessionId:Y}}async function r$($){M0.debug("[auth] Session destroyed");try{await T.deleteFrom("sessions").where("id","=",$).execute()}catch(W){M0.debug(`[auth] Session destroy failed: ${W.message}`)}}async function h0($){try{await T.deleteFrom("sessions").where("user_id","=",$).execute()}catch(W){let Z=W instanceof Error?W.message:String(W);if(Z.includes("sessions")&&/no such table|does not exist|doesn't exist/i.test(Z))return;throw W}}async function p0($){try{let W=await T.selectFrom("sessions").where("id","=",$).selectAll().executeTakeFirst();if(!W)return;let Z=W.expires_at?new Date(String(W.expires_at)).getTime():0;if(Date.now()>Z){await T.deleteFrom("sessions").where("id","=",$).execute();return}return await Y1.find(W.user_id)}catch{return}}async function s$($){try{let W=await T.selectFrom("sessions").where("id","=",$).selectAll().executeTakeFirst();if(!W)return!1;let Z=W.expires_at?new Date(String(W.expires_at)).getTime():0;if(Date.now()>Z)return await T.deleteFrom("sessions").where("id","=",$).execute(),!1;return!0}catch{return!1}}async function e$($,W=86400000){try{let Z=await T.selectFrom("sessions").where("id","=",$).selectAll().executeTakeFirst();if(!Z)return!1;let J=Z.expires_at?new Date(String(Z.expires_at)).getTime():0;if(Date.now()>J)return await T.deleteFrom("sessions").where("id","=",$).execute(),!1;let Q=new Date(Date.now()+W);return await T.updateTable("sessions").set({expires_at:Q.toISOString(),last_activity:Math.floor(Date.now()/1000)}).where("id","=",$).execute(),!0}catch{return!1}}var F2={login:a$,logout:r$,destroyAll:h0,user:p0,check:s$,refresh:e$};Y0();function m0(){return g.auth.passwordReset?.expire??60}function V1($){let W=$.expires_at;if(typeof W==="string"||W instanceof Date)return new Date(W).getTime()>Date.now();let Z=$.created_at;if(typeof Z==="string"||Z instanceof Date){let J=m0();return new Date(Z).getTime()+J*60000>Date.now()}return!1}async function JW($){let W=g.app.name||"Stacks",Z=g.app.supportEmail||g.email?.from?.address||"",J=new Date().toLocaleString("en-US",{dateStyle:"full",timeStyle:"short"});try{let{html:Q,text:G}=await F1("password-changed",{subject:`Your ${W} password has been changed`,variables:{changedAt:J,supportEmail:Z}});if(!Q&&!G){await U0.send({to:$,subject:`Your ${W} password has been changed`,text:`Your ${W} password was changed on ${J}.${Z?` If this wasn't you, contact ${Z}.`:""}`});return}await U0.send({to:$,subject:`Your ${W} password has been changed`,text:G,html:Q})}catch(Q){console.error("[PasswordReset] Failed to send password changed notification:",Q)}}function C2($){function W(){return $W(32).toString("hex")}async function Z(){let X=W(),K=await K1(X,{algorithm:"bcrypt"}),Y=m0(),L=new Date(Date.now()+Y*60000).toISOString();return await n.deleteFrom("password_resets").where("email","=",$).execute(),await n.insertInto("password_resets").values({email:$,token:K,expires_at:L}).executeTakeFirst(),X}async function J(){if(!await n.selectFrom("users").where("email","=",$).selectAll().executeTakeFirst())return;let K=await Z(),Y=m0(),L=g.app.name||"Stacks",O=g.app.url?`https://${g.app.url}`:`http://localhost:${process.env.PORT||"3000"}`,E=(g.auth.passwordReset?.url??"/password/reset/{token}?email={email}").replace("{token}",K).replace("{email}",encodeURIComponent($)),F=/^https?:\/\//.test(E)?E:`${O}${E.startsWith("/")?"":"/"}${E}`;try{let{html:j,text:C}=await F1("password-reset",{subject:`Reset Your ${L} Password`,variables:{resetUrl:F,expireMinutes:Y}});if(!j&&!C)throw Error("password-reset template missing or rendered empty");await U0.send({to:$,subject:`Reset Your ${L} Password`,text:C,html:j})}catch(j){let C=j instanceof Error?j.message:String(j);console.warn(`[PasswordReset] template render failed, sending plain-text fallback: ${C}`),await U0.send({to:$,subject:`Reset Your ${L} Password`,text:`Reset your password by visiting: ${F}
162
162
 
163
- This link expires in ${Y} minutes. If you didn't request this, you can safely ignore this email.`})}}async function Q(X){let K=await t.selectFrom("password_resets").where("email","=",$).selectAll().executeTakeFirst();if(!K)return!1;if(!H1(K))return await t.deleteFrom("password_resets").where("email","=",$).execute(),!1;let Y=K.token;return await j1(X,Y)}async function G(X,K){let Y=await t.transaction(async(L)=>{let O=L,_=await O.selectFrom("password_resets").where("email","=",$).selectAll().executeTakeFirst();if(!_)return{success:!1,message:"Invalid or expired reset token"};if(!H1(_))return await O.deleteFrom("password_resets").where("email","=",$).execute(),{success:!1,message:"This password reset link has expired. Please request a new one."};let E=_.token;if(!await j1(X,E))return{success:!1,message:"Invalid or expired reset token"};let H=await O.selectFrom("users").where("email","=",$).selectAll().executeTakeFirst();if(!H)return{success:!1,message:"Invalid or expired reset token"};let P=await D1(K,{algorithm:"bcrypt"});try{await O.updateTable("users").set({password:P,password_changed_at:BW(new Date)}).where("email","=",$).executeTakeFirst()}catch(T){let A=T instanceof Error?T.message:String(T);if(/password_changed_at|no such column|unknown column/i.test(A))FW.warn("[PasswordReset] password_changed_at column missing \u2014 run `buddy migrate`; resetting without the credential-version stamp"),await O.updateTable("users").set({password:P}).where("email","=",$).executeTakeFirst();else throw T}return await O.deleteFrom("password_resets").where("email","=",$).execute(),{success:!0,userId:Number(H.id)}});if(Y.success)return await j0(Y.userId),await m0(Y.userId),OW($).catch((L)=>{console.error("[PasswordReset] Failed to send notification:",L)}),{success:!0};return Y}return{sendEmail:J,verifyToken:Q,resetPassword:G}}import{db as zW}from"@stacksjs/database";import{HttpError as P0}from"@stacksjs/error-handling";import{User as DW}from"@stacksjs/orm";import{makeHash as jW}from"@stacksjs/security";import{db as D}from"@stacksjs/database";import{isUniqueViolation as t0}from"@stacksjs/orm";function i0($){if(!t0($))throw $}function I($){if(!$)return null;return{id:Number($.id),name:String($.name),guard_name:String($.guard_name),description:$.description==null?void 0:String($.description),created_at:$.created_at==null?void 0:String($.created_at),updated_at:$.updated_at==null?void 0:String($.updated_at)}}async function U1($,W,Z,J){await D.insertInto($).values({name:W,guard_name:Z,description:J??null}).execute();let Q=await D.selectFrom($).selectAll().where("name","=",W).where("guard_name","=",Z).orderBy("id","desc").limit(1).executeTakeFirst(),G=I(Q);if(!G)throw Error(`[rbac] insertAndFetch(${$}, ${W}, ${Z}) succeeded but follow-up SELECT returned nothing`);return G}async function l0($,W){let Z=D.selectFrom($).select("user_id"in W?"user_id":"role_id");for(let[Q,G]of Object.entries(W))Z=Z.where(Q,"=",G);if(await Z.limit(1).executeTakeFirst())return;try{await D.insertInto($).values(W).execute()}catch(Q){i0(Q)}}async function d0($,W){let Z=D.deleteFrom($);for(let[J,Q]of Object.entries(W))Z=Z.where(J,"=",Q);await Z.execute()}async function q1($,W,Z){await D.deleteFrom($).where(W,"=",Z).execute()}async function n0($,W,Z,J,Q){let G=Array.from(new Set(Q));await D.transaction(async(X)=>{let K=X;if(await K.deleteFrom($).where(W,"=",Z).execute(),G.length===0)return;let Y=G.map((L)=>({[W]:Z,[J]:L}));try{await K.insertInto($).values(Y).execute()}catch(L){i0(L);for(let O of G)try{await K.insertInto($).values({[W]:Z,[J]:O}).execute()}catch(_){i0(_)}}})}function _W(){return{async findRoleByName($,W="web"){let Z=await D.selectFrom("roles").selectAll().where("name","=",$).where("guard_name","=",W).limit(1).executeTakeFirst();return I(Z)},async findRoleById($){let W=await D.selectFrom("roles").selectAll().where("id","=",$).limit(1).executeTakeFirst();return I(W)},async createRole($,W="web",Z){return await U1("roles",$,W,Z)},async deleteRole($){await D.deleteFrom("user_roles").where("role_id","=",$).execute(),await D.deleteFrom("role_permissions").where("role_id","=",$).execute(),await D.deleteFrom("roles").where("id","=",$).execute()},async getAllRoles($){let W=D.selectFrom("roles").selectAll();if($)W=W.where("guard_name","=",$);return(await W.orderBy("id","asc").execute()).map((J)=>I(J)).filter(Boolean)},async findPermissionByName($,W="web"){let Z=await D.selectFrom("permissions").selectAll().where("name","=",$).where("guard_name","=",W).limit(1).executeTakeFirst();return I(Z)},async findPermissionById($){let W=await D.selectFrom("permissions").selectAll().where("id","=",$).limit(1).executeTakeFirst();return I(W)},async createPermission($,W="web",Z){return await U1("permissions",$,W,Z)},async deletePermission($){await D.deleteFrom("user_permissions").where("permission_id","=",$).execute(),await D.deleteFrom("role_permissions").where("permission_id","=",$).execute(),await D.deleteFrom("permissions").where("id","=",$).execute()},async getAllPermissions($){let W=D.selectFrom("permissions").selectAll();if($)W=W.where("guard_name","=",$);return(await W.orderBy("id","asc").execute()).map((J)=>I(J)).filter(Boolean)},async getUserRoles($){return(await D.selectFrom("roles").innerJoin("user_roles","user_roles.role_id","=","roles.id").select(["roles.id as id","roles.name as name","roles.guard_name as guard_name","roles.description as description","roles.created_at as created_at","roles.updated_at as updated_at"]).where("user_roles.user_id","=",$).orderBy("roles.id","asc").execute()).map((Z)=>I(Z)).filter(Boolean)},assignRoleToUser($,W){return l0("user_roles",{user_id:$,role_id:W})},removeRoleFromUser($,W){return d0("user_roles",{user_id:$,role_id:W})},removeAllRolesFromUser($){return q1("user_roles","user_id",$)},syncUserRoles($,W){return n0("user_roles","user_id",$,"role_id",W)},async getUserDirectPermissions($){return(await D.selectFrom("permissions").innerJoin("user_permissions","user_permissions.permission_id","=","permissions.id").select(["permissions.id as id","permissions.name as name","permissions.guard_name as guard_name","permissions.description as description","permissions.created_at as created_at","permissions.updated_at as updated_at"]).where("user_permissions.user_id","=",$).orderBy("permissions.id","asc").execute()).map((Z)=>I(Z)).filter(Boolean)},assignPermissionToUser($,W){return l0("user_permissions",{user_id:$,permission_id:W})},removePermissionFromUser($,W){return d0("user_permissions",{user_id:$,permission_id:W})},removeAllPermissionsFromUser($){return q1("user_permissions","user_id",$)},syncUserPermissions($,W){return n0("user_permissions","user_id",$,"permission_id",W)},async getRolePermissions($){return(await D.selectFrom("permissions").innerJoin("role_permissions","role_permissions.permission_id","=","permissions.id").select(["permissions.id as id","permissions.name as name","permissions.guard_name as guard_name","permissions.description as description","permissions.created_at as created_at","permissions.updated_at as updated_at"]).where("role_permissions.role_id","=",$).orderBy("permissions.id","asc").execute()).map((Z)=>I(Z)).filter(Boolean)},assignPermissionToRole($,W){return l0("role_permissions",{role_id:$,permission_id:W})},removePermissionFromRole($,W){return d0("role_permissions",{role_id:$,permission_id:W})},syncRolePermissions($,W){return n0("role_permissions","role_id",$,"permission_id",W)}}}var HW=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;async function l2($){let{email:W,password:Z,name:J}=$;if(typeof W!=="string"||W.length>254||!HW.test(W))throw new P0(422,"Email address is invalid");if(typeof Z!=="string"||Z.length<8)throw new P0(422,"Password must be at least 8 characters");let Q=await jW(Z,{algorithm:"bcrypt"}),G=await zW.transaction(async(K)=>{let Y=K;if(await Y.selectFrom("users").where("email","=",W).selectAll().executeTakeFirst())throw new P0(409,"Email already exists");try{await Y.insertInto("users").values({email:W,password:Q,name:J}).execute()}catch(_){if(t0(_))throw new P0(409,"Email already exists");throw _}let O=await Y.selectFrom("users").where("email","=",W).selectAll().executeTakeFirst();if(!O)throw Error("Failed to retrieve created user");return Number(O.id)}),X=await DW.find(G);if(!X)throw Error("Failed to retrieve created user");return{token:await R.createToken(X,"user-auth-token")}}import{request as $0}from"@stacksjs/router";async function F0(){let $=$0?._authenticatedUser;if($)return $;let W=$0.bearerToken?.();if(!W){let Z=$0.headers?.get?.("authorization")||$0.headers?.get?.("Authorization");if(Z&&Z.startsWith("Bearer "))W=Z.substring(7)}if(!W)return;return await R.getUserFromToken(W)}async function t2(){return F0()}async function MW(){return!!await F0()}async function o2(){return(await F0())?.id}async function a2(){return(await F0())?.email}async function r2(){return(await F0())?.name}async function s2(){return await MW()}async function e2(){await R.logout()}async function $3(){if($0?._authenticatedUser)$0._authenticatedUser=void 0}L0();J0();J0();J0();import{log as c}from"@stacksjs/logging";import*as R0 from"@stacksjs/path";class qW{allow($){return q.allow($)}deny($,W){return q.deny($,W)}denyIf($,W){if($)return this.deny(W);return!0}denyUnless($,W){if(!$)return this.deny(W);return!0}allowIf($,W){if($)return this.allow(W);return!1}}async function CW(){let{fs:$}=await import("@stacksjs/storage"),W=R0.appPath("Policies");if(!$.existsSync(W)){c.debug("No Policies directory found");return}try{let G=(await import(R0.appPath("Gates.ts"))).policies||{};for(let[X,K]of Object.entries(G)){let Y=typeof K==="string"?K:K.policy,L=`${W}/${Y}.ts`;if($.existsSync(L)){let O=await import(L),_=O.default||O[Y];if(_)O0(X,_),c.debug(`Registered policy: ${Y} for ${X}`)}}}catch{c.debug("No Gates.ts found, using convention-based discovery")}let Z=$.readdirSync(W).filter((J)=>J.endsWith("Policy.ts"));for(let J of Z){let Q=J.replace(".ts",""),G=Q.replace("Policy",""),X=`${W}/${J}`;try{let K=await import(X),Y=K.default||K[Q];if(Y)O0(G,Y),c.debug(`Auto-discovered policy: ${Q} for ${G}`)}catch(K){c.error(`Failed to load policy ${Q}:`,K)}}}async function PW(){let{define:$,before:W,after:Z}=await Promise.resolve().then(() => (J0(),I1));try{let Q=await import(R0.appPath("Gates.ts")),G=Q.gates||Q.default?.gates||{};for(let[Y,L]of Object.entries(G))if(typeof L==="function")$(Y,L),c.debug(`Registered gate: ${Y}`);let X=Q.before||Q.default?.before||[];for(let Y of X)if(typeof Y==="function")W(Y);let K=Q.after||Q.default?.after||[];for(let Y of K)if(typeof Y==="function")Z(Y);c.debug("Gates registered successfully")}catch{c.debug("No Gates.ts found or failed to load")}}async function G3(){await PW(),await CW()}J0();async function vW($,W,...Z){return v0(W,$,...Z)}async function SW($,W,...Z){return S0(W,$,...Z)}async function EW($,W,...Z){return _0(W,$,...Z)}async function xW($,W,...Z){return E0(W,$,...Z)}async function RW($,W,...Z){return x0(W,$,...Z)}async function K3($,W,...Z){return W0(W,$,...Z)}function L3($){return Object.assign($,{can:(Z,...J)=>vW($,Z,...J),cannot:(Z,...J)=>SW($,Z,...J),canAny:(Z,...J)=>EW($,Z,...J),canAll:(Z,...J)=>xW($,Z,...J),authorize:(Z,...J)=>RW($,Z,...J)})}class A0{max;map=new Map;constructor($){this.max=$}get($){return this.map.get($)}has($){return this.map.has($)}set($,W){if(this.map.has($))this.map.delete($);if(this.map.set($,W),this.map.size>this.max){let Z=this.map.keys().next().value;if(Z!==void 0)this.map.delete(Z)}return this}delete($){return this.map.delete($)}clear(){this.map.clear()}}var o0=1e4,V={userRoles:new A0(o0),userPermissions:new A0(o0),rolePermissions:new A0(o0),roles:new Map,permissions:new Map},a0=null;function AW($){a0=$,N0()}function j(){if(!a0)throw Error("RBAC store not configured. Call setRbacStore() first.");return a0}function N0(){V.userRoles.clear(),V.userPermissions.clear(),V.rolePermissions.clear(),V.roles.clear(),V.permissions.clear()}function N($){if(typeof $==="number"){if(!Number.isFinite($)||$<=0)throw TypeError("RBAC user id must be a positive number");return $}let W=$.id;if(typeof W!=="number"||!Number.isFinite(W)||W<=0)throw TypeError(`RBAC user id must be a positive number, got ${typeof W} (${String(W)})`);return W}async function r0($,W="web",Z){let J=await j().createRole($,W,Z);return V.roles.set(`${$}:${W}`,J),J}async function b($,W="web"){let Z=`${$}:${W}`;if(V.roles.has(Z))return V.roles.get(Z);let J=await j().findRoleByName($,W);if(J)V.roles.set(Z,J);return J}async function NW($,W="web"){let Z=await b($,W);if(Z)await j().deleteRole(Z.id),V.roles.delete(`${$}:${W}`),N0()}async function yW($){return j().getAllRoles($)}async function TW($,W="web",Z){let J=await j().createPermission($,W,Z);return V.permissions.set(`${$}:${W}`,J),J}async function u($,W="web"){let Z=`${$}:${W}`;if(V.permissions.has(Z))return V.permissions.get(Z);let J=await j().findPermissionByName($,W);if(J)V.permissions.set(Z,J);return J}async function wW($,W="web"){let Z=await u($,W);if(Z)await j().deletePermission(Z.id),V.permissions.delete(`${$}:${W}`),N0()}async function fW($){return j().getAllPermissions($)}async function Q0($){let W=N($);if(V.userRoles.has(W))return V.userRoles.get(W);let Z=await j().getUserRoles(W);return V.userRoles.set(W,Z),Z}async function b1($,W,Z="web"){let J=N($),Q=await b(W,Z);if(!Q)throw Error(`Role '${W}' not found.`);await j().assignRoleToUser(J,Q.id),V.userRoles.delete(J),V.userPermissions.delete(J)}async function k1($,W,Z="web"){let J=N($),Q=await b(W,Z);if(!Q)return;await j().removeRoleFromUser(J,Q.id),V.userRoles.delete(J),V.userPermissions.delete(J)}async function IW($){let W=N($);await j().removeAllRolesFromUser(W),V.userRoles.delete(W),V.userPermissions.delete(W)}async function g1($,W,Z="web"){let J=N($),Q=[];for(let G of W){let X=await b(G,Z);if(!X)throw Error(`Role '${G}' not found.`);Q.push(X.id)}await j().syncUserRoles(J,Q),V.userRoles.delete(J),V.userPermissions.delete(J)}async function h1($,W,Z="web"){return(await Q0($)).some((Q)=>Q.name===W&&Q.guard_name===Z)}async function p1($,W,Z="web"){let J=await Q0($);return W.some((Q)=>J.some((G)=>G.name===Q&&G.guard_name===Z))}async function m1($,W,Z="web"){let J=await Q0($);return W.every((Q)=>J.some((G)=>G.name===Q&&G.guard_name===Z))}async function z0($){let W=N($);if(V.userPermissions.has(W))return V.userPermissions.get(W);let Z=await j().getUserDirectPermissions(W),J=await Q0($),Q=[];for(let K of J){let Y=await t1(K.id);Q.push(...Y)}let G=new Set,X=[];for(let K of[...Z,...Q])if(!G.has(K.id))G.add(K.id),X.push(K);return V.userPermissions.set(W,X),X}async function c1($,W,Z="web"){let J=N($),Q=await u(W,Z);if(!Q)throw Error(`Permission '${W}' not found.`);await j().assignPermissionToUser(J,Q.id),V.userPermissions.delete(J)}async function u1($,W,Z="web"){let J=N($),Q=await u(W,Z);if(!Q)return;await j().removePermissionFromUser(J,Q.id),V.userPermissions.delete(J)}async function bW($){let W=N($);await j().removeAllPermissionsFromUser(W),V.userPermissions.delete(W)}async function l1($,W,Z="web"){let J=N($),Q=[];for(let G of W){let X=await u(G,Z);if(!X)throw Error(`Permission '${G}' not found.`);Q.push(X.id)}await j().syncUserPermissions(J,Q),V.userPermissions.delete(J)}async function d1($,W,Z="web"){return(await z0($)).some((Q)=>Q.name===W&&Q.guard_name===Z)}async function n1($,W,Z="web"){let J=await z0($);return W.some((Q)=>J.some((G)=>G.name===Q&&G.guard_name===Z))}async function i1($,W,Z="web"){let J=await z0($);return W.every((Q)=>J.some((G)=>G.name===Q&&G.guard_name===Z))}async function t1($){if(V.rolePermissions.has($))return V.rolePermissions.get($);let W=await j().getRolePermissions($);return V.rolePermissions.set($,W),W}async function kW($,W,Z="web"){let J=await b($,Z);if(!J)throw Error(`Role '${$}' not found.`);let Q=await u(W,Z);if(!Q)throw Error(`Permission '${W}' not found.`);await j().assignPermissionToRole(J.id,Q.id),V.rolePermissions.delete(J.id),V.userPermissions.clear()}async function gW($,W,Z="web"){let J=await b($,Z);if(!J)return;let Q=await u(W,Z);if(!Q)return;await j().removePermissionFromRole(J.id,Q.id),V.rolePermissions.delete(J.id),V.userPermissions.clear()}async function hW($,W,Z="web"){let J=await b($,Z);if(!J)throw Error(`Role '${$}' not found.`);let Q=[];for(let G of W){let X=await u(G,Z);if(!X)throw Error(`Permission '${G}' not found.`);Q.push(X.id)}await j().syncRolePermissions(J.id,Q),V.rolePermissions.delete(J.id),V.userPermissions.clear()}function pW($){let W=N($);return Object.assign($,{hasRole:(J,Q)=>h1(W,J,Q),hasAnyRole:(J,Q)=>p1(W,J,Q),hasAllRoles:(J,Q)=>m1(W,J,Q),hasPermission:(J,Q)=>d1(W,J,Q),hasAnyPermission:(J,Q)=>n1(W,J,Q),hasAllPermissions:(J,Q)=>i1(W,J,Q),getRoles:()=>Q0(W),getPermissions:()=>z0(W),assignRole:(J,Q)=>b1(W,J,Q),removeRole:(J,Q)=>k1(W,J,Q),syncRoles:(J,Q)=>g1(W,J,Q),givePermission:(J,Q)=>c1(W,J,Q),revokePermission:(J,Q)=>u1(W,J,Q),syncPermissions:(J,Q)=>l1(W,J,Q)})}var F3={setStore:AW,flushCache:N0,createRole:r0,findRole:b,deleteRole:NW,getAllRoles:yW,createPermission:TW,findPermission:u,deletePermission:wW,getAllPermissions:fW,getUserRoles:Q0,assignRole:b1,removeRole:k1,removeAllRoles:IW,syncRoles:g1,hasRole:h1,hasAnyRole:p1,hasAllRoles:m1,getUserPermissions:z0,givePermission:c1,revokePermission:u1,revokeAllPermissions:bW,syncPermissions:l1,hasPermission:d1,hasAnyPermission:n1,hasAllPermissions:i1,getRolePermissions:t1,givePermissionToRole:kW,revokePermissionFromRole:gW,syncRolePermissions:hW,withRbac:pW};var o1=[{name:"admin",guard_name:"web",description:"Full access. Sees every dashboard surface, every model, every infra control."},{name:"dev",guard_name:"web",description:"Developer / infra. Sees dev-mode surfaces (CI, query inspector, runner alerts) but not billing/admin-only management."},{name:"client",guard_name:"web",description:"End user / client. Sees content, orders, profile, billing \u2014 no dev tools, no infra surfaces."}];async function mW(){let $=[],W=[];for(let Z of o1){if(await b(Z.name,Z.guard_name)){W.push({name:Z.name,guard_name:Z.guard_name,reason:"already_exists"});continue}let Q=await r0(Z.name,Z.guard_name,Z.description);$.push(Q)}return{created:$,skipped:W}}import{Buffer as a1}from"buffer";import{createHmac as s1,randomBytes as cW,timingSafeEqual as uW}from"crypto";import{config as G0}from"@stacksjs/config";import{db as o}from"@stacksjs/database";import{mail as r1,template as lW}from"@stacksjs/email";import{log as dW}from"@stacksjs/logging";function e1(){let $=G0.app.key;if(typeof $!=="string"||$.length===0)throw Error("[auth] config.app.key is not set \u2014 email-verification HMAC requires a real APP_KEY. "+"Run `./buddy key:generate` to provision one, or set the APP_KEY env var before booting the app.");return $}function nW($){let W=cW(32).toString("hex"),Z=`${$}:${W}`,J=s1("sha256",e1()).update(Z).digest("hex");return{token:W,hash:J}}function iW($,W,Z){let J=`${$}:${W}`,Q=s1("sha256",e1()).update(J).digest("hex"),G=a1.from(Q),X=a1.from(Z);if(G.length!==X.length)return!1;return uW(G,X)}function tW(){let W=(G0.auth??{}).emailVerification;if(W!=null&&typeof W==="object"){let Z=W;if(typeof Z.expire==="number")return Z.expire}return 60}function oW($,W){let Z=G0.app.url?`https://${G0.app.url}`:`http://localhost:${process.env.PORT||"3000"}`,Q=(G0.auth.emailVerification?.url??"/verify-email/{id}/{token}").replace("{id}",String($)).replace("{token}",W);return/^https?:\/\//.test(Q)?Q:`${Z}${Q.startsWith("/")?"":"/"}${Q}`}function $$($){return $.email_verified_at!=null}async function W$($){let{token:W,hash:Z}=nW($.id),J=tW(),Q=new Date(Date.now()+J*60*1000);await o.deleteFrom("email_verifications").where("user_id","=",$.id).execute(),await o.insertInto("email_verifications").values({user_id:$.id,token:Z,expires_at:Q.toISOString()}).executeTakeFirst();let G=oW($.id,W),X=G0.app.name||"Stacks";try{let{html:K,text:Y}=await lW("email-verification",{subject:`Verify Your ${X} Email Address`,variables:{verificationUrl:G,expiryMinutes:J,userName:$.name||$.email}});if(!K&&!Y)throw Error("email-verification template missing or rendered empty");await r1.send({to:$.email,subject:`Verify Your ${X} Email Address`,text:Y,html:K})}catch(K){let Y=K instanceof Error?K.message:String(K);dW.warn(`[email] Email verification template failed, using plain text fallback: ${Y}`),await r1.send({to:$.email,subject:`Verify Your ${X} Email Address`,text:`Please verify your email address by visiting: ${G}
163
+ This link expires in ${Y} minutes. If you didn't request this, you can safely ignore this email.`})}}async function Q(X){let K=await n.selectFrom("password_resets").where("email","=",$).selectAll().executeTakeFirst();if(!K)return!1;if(!V1(K))return await n.deleteFrom("password_resets").where("email","=",$).execute(),!1;let Y=K.token;return await L1(X,Y)}async function G(X,K){let Y=await n.transaction(async(L)=>{let O=L,_=await O.selectFrom("password_resets").where("email","=",$).selectAll().executeTakeFirst();if(!_)return{success:!1,message:"Invalid or expired reset token"};if(!V1(_))return await O.deleteFrom("password_resets").where("email","=",$).execute(),{success:!1,message:"This password reset link has expired. Please request a new one."};let E=_.token;if(!await L1(X,E))return{success:!1,message:"Invalid or expired reset token"};let j=await O.selectFrom("users").where("email","=",$).selectAll().executeTakeFirst();if(!j)return{success:!1,message:"Invalid or expired reset token"};let C=await K1(K,{algorithm:"bcrypt"});try{await O.updateTable("users").set({password:C,password_changed_at:ZW(new Date)}).where("email","=",$).executeTakeFirst()}catch(N){let R=N instanceof Error?N.message:String(N);if(/password_changed_at|no such column|unknown column/i.test(R))WW.warn("[PasswordReset] password_changed_at column missing \u2014 run `buddy migrate`; resetting without the credential-version stamp"),await O.updateTable("users").set({password:C}).where("email","=",$).executeTakeFirst();else throw N}return await O.deleteFrom("password_resets").where("email","=",$).execute(),{success:!0,userId:Number(j.id)}});if(Y.success)return await z0(Y.userId),await h0(Y.userId),JW($).catch((L)=>{console.error("[PasswordReset] Failed to send notification:",L)}),{success:!0};return Y}return{sendEmail:J,verifyToken:Q,resetPassword:G}}import{db as QW}from"@stacksjs/database";import{HttpError as q0}from"@stacksjs/error-handling";import{User as GW}from"@stacksjs/orm";import{makeHash as XW}from"@stacksjs/security";import{db as E2}from"@stacksjs/database";import{isUniqueViolation as B1}from"@stacksjs/orm";var YW=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;async function f2($){let{email:W,password:Z,name:J}=$;if(typeof W!=="string"||W.length>254||!YW.test(W))throw new q0(422,"Email address is invalid");if(typeof Z!=="string"||Z.length<8)throw new q0(422,"Password must be at least 8 characters");let Q=await XW(Z,{algorithm:"bcrypt"}),G=await QW.transaction(async(K)=>{let Y=K;if(await Y.selectFrom("users").where("email","=",W).selectAll().executeTakeFirst())throw new q0(409,"Email already exists");try{await Y.insertInto("users").values({email:W,password:Q,name:J}).execute()}catch(_){if(B1(_))throw new q0(409,"Email already exists");throw _}let O=await Y.selectFrom("users").where("email","=",W).selectAll().executeTakeFirst();if(!O)throw Error("Failed to retrieve created user");return Number(O.id)}),X=await GW.find(G);if(!X)throw Error("Failed to retrieve created user");return{token:await x.createToken(X,"user-auth-token")}}import{request as s}from"@stacksjs/router";async function L0(){let $=s?._authenticatedUser;if($)return $;let W=s.bearerToken?.();if(!W){let Z=s.headers?.get?.("authorization")||s.headers?.get?.("Authorization");if(Z&&Z.startsWith("Bearer "))W=Z.substring(7)}if(!W)return;return await x.getUserFromToken(W)}async function g2(){return L0()}async function KW(){return!!await L0()}async function h2(){return(await L0())?.id}async function p2(){return(await L0())?.email}async function m2(){return(await L0())?.name}async function c2(){return await KW()}async function u2(){await x.logout()}async function l2(){if(s?._authenticatedUser)s._authenticatedUser=void 0}Y0();W0();W0();W0();import{log as h}from"@stacksjs/logging";import*as S0 from"@stacksjs/path";class VW{allow($){return U.allow($)}deny($,W){return U.deny($,W)}denyIf($,W){if($)return this.deny(W);return!0}denyUnless($,W){if(!$)return this.deny(W);return!0}allowIf($,W){if($)return this.allow(W);return!1}}async function FW(){let{fs:$}=await import("@stacksjs/storage"),W=S0.appPath("Policies");if(!$.existsSync(W)){h.debug("No Policies directory found");return}try{let G=(await import(S0.appPath("Gates.ts"))).policies||{};for(let[X,K]of Object.entries(G)){let Y=typeof K==="string"?K:K.policy,L=`${W}/${Y}.ts`;if($.existsSync(L)){let O=await import(L),_=O.default||O[Y];if(_)F0(X,_),h.debug(`Registered policy: ${Y} for ${X}`)}}}catch{h.debug("No Gates.ts found, using convention-based discovery")}let Z=$.readdirSync(W).filter((J)=>J.endsWith("Policy.ts"));for(let J of Z){let Q=J.replace(".ts",""),G=Q.replace("Policy",""),X=`${W}/${J}`;try{let K=await import(X),Y=K.default||K[Q];if(Y)F0(G,Y),h.debug(`Auto-discovered policy: ${Q} for ${G}`)}catch(K){h.error(`Failed to load policy ${Q}:`,K)}}}async function BW(){let{define:$,before:W,after:Z}=await Promise.resolve().then(() => (W0(),S1));try{let Q=await import(S0.appPath("Gates.ts")),G=Q.gates||Q.default?.gates||{};for(let[Y,L]of Object.entries(G))if(typeof L==="function")$(Y,L),h.debug(`Registered gate: ${Y}`);let X=Q.before||Q.default?.before||[];for(let Y of X)if(typeof Y==="function")W(Y);let K=Q.after||Q.default?.after||[];for(let Y of K)if(typeof Y==="function")Z(Y);h.debug("Gates registered successfully")}catch{h.debug("No Gates.ts found or failed to load")}}async function o2(){await BW(),await FW()}W0();async function OW($,W,...Z){return C0(W,$,...Z)}async function _W($,W,...Z){return P0(W,$,...Z)}async function zW($,W,...Z){return B0(W,$,...Z)}async function DW($,W,...Z){return v0(W,$,...Z)}async function jW($,W,...Z){return E0(W,$,...Z)}async function s2($,W,...Z){return e(W,$,...Z)}function e2($){return Object.assign($,{can:(Z,...J)=>OW($,Z,...J),cannot:(Z,...J)=>_W($,Z,...J),canAny:(Z,...J)=>zW($,Z,...J),canAll:(Z,...J)=>DW($,Z,...J),authorize:(Z,...J)=>jW($,Z,...J)})}class x0{max;map=new Map;constructor($){this.max=$}get($){return this.map.get($)}has($){return this.map.has($)}set($,W){if(this.map.has($))this.map.delete($);if(this.map.set($,W),this.map.size>this.max){let Z=this.map.keys().next().value;if(Z!==void 0)this.map.delete(Z)}return this}delete($){return this.map.delete($)}clear(){this.map.clear()}}var c0=1e4,V={userRoles:new x0(c0),userPermissions:new x0(c0),rolePermissions:new x0(c0),roles:new Map,permissions:new Map},u0=null;function HW($){u0=$,R0()}function D(){if(!u0)throw Error("RBAC store not configured. Call setRbacStore() first.");return u0}function R0(){V.userRoles.clear(),V.userPermissions.clear(),V.rolePermissions.clear(),V.roles.clear(),V.permissions.clear()}function A($){if(typeof $==="number"){if(!Number.isFinite($)||$<=0)throw TypeError("RBAC user id must be a positive number");return $}let W=$.id;if(typeof W!=="number"||!Number.isFinite(W)||W<=0)throw TypeError(`RBAC user id must be a positive number, got ${typeof W} (${String(W)})`);return W}async function MW($,W="web",Z){let J=await D().createRole($,W,Z);return V.roles.set(`${$}:${W}`,J),J}async function p($,W="web"){let Z=`${$}:${W}`;if(V.roles.has(Z))return V.roles.get(Z);let J=await D().findRoleByName($,W);if(J)V.roles.set(Z,J);return J}async function UW($,W="web"){let Z=await p($,W);if(Z)await D().deleteRole(Z.id),V.roles.delete(`${$}:${W}`),R0()}async function qW($){return D().getAllRoles($)}async function CW($,W="web",Z){let J=await D().createPermission($,W,Z);return V.permissions.set(`${$}:${W}`,J),J}async function m($,W="web"){let Z=`${$}:${W}`;if(V.permissions.has(Z))return V.permissions.get(Z);let J=await D().findPermissionByName($,W);if(J)V.permissions.set(Z,J);return J}async function PW($,W="web"){let Z=await m($,W);if(Z)await D().deletePermission(Z.id),V.permissions.delete(`${$}:${W}`),R0()}async function vW($){return D().getAllPermissions($)}async function Z0($){let W=A($);if(V.userRoles.has(W))return V.userRoles.get(W);let Z=await D().getUserRoles(W);return V.userRoles.set(W,Z),Z}async function x1($,W,Z="web"){let J=A($),Q=await p(W,Z);if(!Q)throw Error(`Role '${W}' not found.`);await D().assignRoleToUser(J,Q.id),V.userRoles.delete(J),V.userPermissions.delete(J)}async function R1($,W,Z="web"){let J=A($),Q=await p(W,Z);if(!Q)return;await D().removeRoleFromUser(J,Q.id),V.userRoles.delete(J),V.userPermissions.delete(J)}async function EW($){let W=A($);await D().removeAllRolesFromUser(W),V.userRoles.delete(W),V.userPermissions.delete(W)}async function A1($,W,Z="web"){let J=A($),Q=[];for(let G of W){let X=await p(G,Z);if(!X)throw Error(`Role '${G}' not found.`);Q.push(X.id)}await D().syncUserRoles(J,Q),V.userRoles.delete(J),V.userPermissions.delete(J)}async function y1($,W,Z="web"){return(await Z0($)).some((Q)=>Q.name===W&&Q.guard_name===Z)}async function N1($,W,Z="web"){let J=await Z0($);return W.some((Q)=>J.some((G)=>G.name===Q&&G.guard_name===Z))}async function w1($,W,Z="web"){let J=await Z0($);return W.every((Q)=>J.some((G)=>G.name===Q&&G.guard_name===Z))}async function O0($){let W=A($);if(V.userPermissions.has(W))return V.userPermissions.get(W);let Z=await D().getUserDirectPermissions(W),J=await Z0($),Q=[];for(let K of J){let Y=await h1(K.id);Q.push(...Y)}let G=new Set,X=[];for(let K of[...Z,...Q])if(!G.has(K.id))G.add(K.id),X.push(K);return V.userPermissions.set(W,X),X}async function T1($,W,Z="web"){let J=A($),Q=await m(W,Z);if(!Q)throw Error(`Permission '${W}' not found.`);await D().assignPermissionToUser(J,Q.id),V.userPermissions.delete(J)}async function f1($,W,Z="web"){let J=A($),Q=await m(W,Z);if(!Q)return;await D().removePermissionFromUser(J,Q.id),V.userPermissions.delete(J)}async function SW($){let W=A($);await D().removeAllPermissionsFromUser(W),V.userPermissions.delete(W)}async function I1($,W,Z="web"){let J=A($),Q=[];for(let G of W){let X=await m(G,Z);if(!X)throw Error(`Permission '${G}' not found.`);Q.push(X.id)}await D().syncUserPermissions(J,Q),V.userPermissions.delete(J)}async function b1($,W,Z="web"){return(await O0($)).some((Q)=>Q.name===W&&Q.guard_name===Z)}async function k1($,W,Z="web"){let J=await O0($);return W.some((Q)=>J.some((G)=>G.name===Q&&G.guard_name===Z))}async function g1($,W,Z="web"){let J=await O0($);return W.every((Q)=>J.some((G)=>G.name===Q&&G.guard_name===Z))}async function h1($){if(V.rolePermissions.has($))return V.rolePermissions.get($);let W=await D().getRolePermissions($);return V.rolePermissions.set($,W),W}async function xW($,W,Z="web"){let J=await p($,Z);if(!J)throw Error(`Role '${$}' not found.`);let Q=await m(W,Z);if(!Q)throw Error(`Permission '${W}' not found.`);await D().assignPermissionToRole(J.id,Q.id),V.rolePermissions.delete(J.id),V.userPermissions.clear()}async function RW($,W,Z="web"){let J=await p($,Z);if(!J)return;let Q=await m(W,Z);if(!Q)return;await D().removePermissionFromRole(J.id,Q.id),V.rolePermissions.delete(J.id),V.userPermissions.clear()}async function AW($,W,Z="web"){let J=await p($,Z);if(!J)throw Error(`Role '${$}' not found.`);let Q=[];for(let G of W){let X=await m(G,Z);if(!X)throw Error(`Permission '${G}' not found.`);Q.push(X.id)}await D().syncRolePermissions(J.id,Q),V.rolePermissions.delete(J.id),V.userPermissions.clear()}function yW($){let W=A($);return Object.assign($,{hasRole:(J,Q)=>y1(W,J,Q),hasAnyRole:(J,Q)=>N1(W,J,Q),hasAllRoles:(J,Q)=>w1(W,J,Q),hasPermission:(J,Q)=>b1(W,J,Q),hasAnyPermission:(J,Q)=>k1(W,J,Q),hasAllPermissions:(J,Q)=>g1(W,J,Q),getRoles:()=>Z0(W),getPermissions:()=>O0(W),assignRole:(J,Q)=>x1(W,J,Q),removeRole:(J,Q)=>R1(W,J,Q),syncRoles:(J,Q)=>A1(W,J,Q),givePermission:(J,Q)=>T1(W,J,Q),revokePermission:(J,Q)=>f1(W,J,Q),syncPermissions:(J,Q)=>I1(W,J,Q)})}var W3={setStore:HW,flushCache:R0,createRole:MW,findRole:p,deleteRole:UW,getAllRoles:qW,createPermission:CW,findPermission:m,deletePermission:PW,getAllPermissions:vW,getUserRoles:Z0,assignRole:x1,removeRole:R1,removeAllRoles:EW,syncRoles:A1,hasRole:y1,hasAnyRole:N1,hasAllRoles:w1,getUserPermissions:O0,givePermission:T1,revokePermission:f1,revokeAllPermissions:SW,syncPermissions:I1,hasPermission:b1,hasAnyPermission:k1,hasAllPermissions:g1,getRolePermissions:h1,givePermissionToRole:xW,revokePermissionFromRole:RW,syncRolePermissions:AW,withRbac:yW};import{Buffer as p1}from"buffer";import{createHmac as c1,randomBytes as NW,timingSafeEqual as wW}from"crypto";import{config as J0}from"@stacksjs/config";import{db as i}from"@stacksjs/database";import{mail as m1,template as TW}from"@stacksjs/email";import{log as fW}from"@stacksjs/logging";function u1(){let $=J0.app.key;if(typeof $!=="string"||$.length===0)throw Error("[auth] config.app.key is not set \u2014 email-verification HMAC requires a real APP_KEY. "+"Run `./buddy key:generate` to provision one, or set the APP_KEY env var before booting the app.");return $}function IW($){let W=NW(32).toString("hex"),Z=`${$}:${W}`,J=c1("sha256",u1()).update(Z).digest("hex");return{token:W,hash:J}}function bW($,W,Z){let J=`${$}:${W}`,Q=c1("sha256",u1()).update(J).digest("hex"),G=p1.from(Q),X=p1.from(Z);if(G.length!==X.length)return!1;return wW(G,X)}function kW(){let W=(J0.auth??{}).emailVerification;if(W!=null&&typeof W==="object"){let Z=W;if(typeof Z.expire==="number")return Z.expire}return 60}function gW($,W){let Z=J0.app.url?`https://${J0.app.url}`:`http://localhost:${process.env.PORT||"3000"}`,Q=(J0.auth.emailVerification?.url??"/verify-email/{id}/{token}").replace("{id}",String($)).replace("{token}",W);return/^https?:\/\//.test(Q)?Q:`${Z}${Q.startsWith("/")?"":"/"}${Q}`}function l1($){return $.email_verified_at!=null}async function d1($){let{token:W,hash:Z}=IW($.id),J=kW(),Q=new Date(Date.now()+J*60*1000);await i.deleteFrom("email_verifications").where("user_id","=",$.id).execute(),await i.insertInto("email_verifications").values({user_id:$.id,token:Z,expires_at:Q.toISOString()}).executeTakeFirst();let G=gW($.id,W),X=J0.app.name||"Stacks";try{let{html:K,text:Y}=await TW("email-verification",{subject:`Verify Your ${X} Email Address`,variables:{verificationUrl:G,expiryMinutes:J,userName:$.name||$.email}});if(!K&&!Y)throw Error("email-verification template missing or rendered empty");await m1.send({to:$.email,subject:`Verify Your ${X} Email Address`,text:Y,html:K})}catch(K){let Y=K instanceof Error?K.message:String(K);fW.warn(`[email] Email verification template failed, using plain text fallback: ${Y}`),await m1.send({to:$.email,subject:`Verify Your ${X} Email Address`,text:`Please verify your email address by visiting: ${G}
164
164
 
165
- This link expires in ${J} minutes.`})}}async function aW($,W){let Z=await o.selectFrom("email_verifications").where("user_id","=",$).selectAll().executeTakeFirst();if(!Z)return{success:!1,message:"No verification request found. Please request a new verification email."};let J=new Date(Z.expires_at);if(new Date>J)return await o.deleteFrom("email_verifications").where("user_id","=",$).execute(),{success:!1,message:"Verification link has expired. Please request a new one."};if(!iW($,W,Z.token))return{success:!1,message:"Invalid verification link."};return await o.updateTable("users").set({email_verified_at:new Date().toISOString()}).where("id","=",$).executeTakeFirst(),await o.deleteFrom("email_verifications").where("user_id","=",$).execute(),{success:!0,message:"Email verified successfully."}}async function rW($){if($$($))return{success:!1,message:"Email is already verified."};let W=await o.selectFrom("email_verifications").where("user_id","=",$.id).selectAll().executeTakeFirst();if(W){let Z=new Date(W.created_at),J=(Date.now()-Z.getTime())/1000;if(J<60)return{success:!1,message:`Please wait ${Math.ceil(60-J)} seconds before requesting another verification email.`}}return await W$($),{success:!0,message:"Verification email sent."}}var q3={isVerified:$$,send:W$,verify:aW,resend:rW};import{generateTOTP as J4,verifyTOTP as Q4,generateTOTPSecret as G4,totpKeyUri as X4}from"@stacksjs/ts-auth";import{randomBytes as sW}from"crypto";import{db as y}from"@stacksjs/database";var eW=300;async function Z$($){let W=await y.selectFrom("users").where("id","=",$).select(["two_factor_secret","two_factor_enabled"]).executeTakeFirst();return{secret:W?.two_factor_secret??null,enabled:Boolean(W?.two_factor_enabled)}}function $Z($){return Boolean($.two_factor_enabled)}function WZ($,W){let Z=g0(),J=B1($,W,Z);return{secret:Z,uri:J}}var ZZ=600;async function JZ($,W,Z=ZZ){let J=new Date(Date.now()+Z*1000).toISOString();await y.deleteFrom("two_factor_pending_secrets").where("user_id","=",$).execute(),await y.insertInto("two_factor_pending_secrets").values({user_id:$,secret:W,expires_at:J}).execute()}async function QZ($){let W=await y.selectFrom("two_factor_pending_secrets").where("user_id","=",$).selectAll().executeTakeFirst();if(!W)return null;await y.deleteFrom("two_factor_pending_secrets").where("user_id","=",$).execute();let Z=W.expires_at?new Date(String(W.expires_at)).getTime():0;if(Date.now()>Z)return null;return String(W.secret)}async function GZ($,W,Z){if(!await h0(Z,W))return!1;return await y.updateTable("users").set({two_factor_secret:W,two_factor_enabled:!0}).where("id","=",$).executeTakeFirst(),!0}async function XZ($){await y.updateTable("users").set({two_factor_secret:null,two_factor_enabled:!1}).where("id","=",$).executeTakeFirst()}async function YZ($,W){let{secret:Z,enabled:J}=await Z$($);if(!J||!Z)return!1;return h0(W,Z)}async function KZ($,W=eW){let Z=sW(32).toString("hex"),J=new Date(Date.now()+W*1000).toISOString();return await y.deleteFrom("two_factor_challenges").where("user_id","=",$).execute(),await y.insertInto("two_factor_challenges").values({id:Z,user_id:$,expires_at:J}).execute(),Z}async function LZ($){let W=await y.selectFrom("two_factor_challenges").where("id","=",$).selectAll().executeTakeFirst();if(!W)return null;await y.deleteFrom("two_factor_challenges").where("id","=",$).execute();let Z=W.expires_at?new Date(String(W.expires_at)).getTime():0;if(Date.now()>Z)return null;return Number(W.user_id)}var E3={isEnabled:$Z,getState:Z$,generateSetup:WZ,stashPendingSecret:JZ,consumePendingSecret:QZ,enable:GZ,disable:XZ,verifyLoginCode:YZ,createChallenge:KZ,consumeChallenge:LZ};import{config as l}from"@stacksjs/config";import{db as y0}from"@stacksjs/database";var s0="active_team";function J$($){let W=$.rolePriority??{owner:0,admin:1},Z=[...$.memberships??[]].sort((G,X)=>(W[G.role??""]??2)-(W[X.role??""]??2)),J=$.activeTeamId==null?null:Number($.activeTeamId);if(J!=null&&Number.isFinite(J)){let G=Z.find((X)=>Number(X.team_id)===J);if(G)return{teamId:J,role:G.role??null};if($.allowAnyTeam)return{teamId:J,role:"admin"}}let Q=Z[0];return Q?{teamId:Number(Q.team_id),role:Q.role??null}:{teamId:null,role:null}}function Q$($){let W=$.cookies?.get(s0);if(!W)return null;let Z=Number(W);return Number.isFinite(Z)&&Z>0?Z:null}function T3($,W={}){let Z=Math.max(0,Math.floor(W.maxAgeSeconds??31536000)),J=[`${s0}=${encodeURIComponent(String($))}`,"Path=/","HttpOnly","SameSite=Lax",`Max-Age=${Z}`];if(W.secure)J.push("Secure");return J.join("; ")}function w3(){return`${s0}=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`}async function VZ($){let W=await FZ($);if(!W?.id)return null;let Z=await y0.selectFrom("team_members").where("user_id","=",W.id).where("status","=","active").select(["team_id","role"]).execute();if(Z.length===0)return null;let J=J$({memberships:Z.map((Q)=>({team_id:Number(Q.team_id),role:String(Q.role)})),activeTeamId:Q$($)});return J.teamId!=null?{teamId:J.teamId,role:J.role??String(Z[0].role)}:null}async function f3($,W={}){let Z={user:null,teamId:null,role:null,teams:[],activeTeamId:null},J=l.auth?.default||"api",G=(l.auth?.guards?.[J]?.driver||"token")==="session"?await G$($):await X$($);if(!G?.id)return Z;let X=await y0.selectFrom("team_members").where("user_id","=",G.id).where("status","=","active").select(["team_id","role"]).execute(),K=W.allowAnyTeam?!!W.allowAnyTeam(G):!1,Y=Q$($),L=J$({memberships:X.map((F)=>({team_id:Number(F.team_id),role:String(F.role)})),activeTeamId:Y,allowAnyTeam:K}),O=new Map(X.map((F)=>[Number(F.team_id),String(F.role)])),_=[];if(K)_=await y0.selectFrom("teams").select(["id","name"]).execute();else{let F=[...O.keys()];_=F.length?await y0.selectFrom("teams").whereIn("id",F).select(["id","name"]).execute():[]}let E=_.map((F)=>({id:Number(F.id),name:String(F.name),role:O.get(Number(F.id))||"viewer"})).sort((F,H)=>F.name.localeCompare(H.name));return{user:G,teamId:L.teamId,role:L.role,teams:E,activeTeamId:Y}}async function I3($){let W=await VZ($);return W?W.teamId:null}async function FZ($){let W=l.auth?.default||"api",Q=((l.auth?.guards?.[W]||{driver:"token"}).driver||"token")==="session"?await G$($):await X$($);return Q?.id?Q:void 0}async function G$($){let W=$.cookies?.get("session_id");if(!W)return;return c0(W)}async function X$($){let W=l.auth?.defaultTokenName||"auth-token",Z=(typeof $.bearerToken==="function"?$.bearerToken():void 0)??$.cookies?.get(W);if(!Z)return;return R.getUserFromToken(Z)}export{pW as withRbac,L3 as withAuthorization,YZ as verifyTwoFactorLoginCode,h0 as verifyTwoFactorCode,Q4 as verifyTOTP,Y2 as verifyRegistrationResponse,aW as verifyEmail,K2 as verifyAuthenticationResponse,x$ as validateRefreshToken,SW as userCannot,EW as userCanAny,xW as userCanAll,vW as userCan,eZ as updatePasskeyCounter,X4 as totpKeyUri,U$ as tokens,C$ as tokenCant,v$ as tokenCanAny,P$ as tokenCanAll,X1 as tokenCan,S$ as tokenAbilities,q$ as token,g1 as syncRoles,hW as syncRolePermissions,l1 as syncPermissions,W2 as storeWebAuthnChallenge,JZ as stashPendingTwoFactorSecret,L2 as startRegistration,V2 as startAuthentication,AW as setRbacStore,$2 as setCurrentRegistrationOptions,c0 as sessionUser,LW as sessionRefresh,YW as sessionLogout,XW as sessionLogin,m0 as sessionDestroyAll,KW as sessionCheck,W$ as sendVerificationEmail,J$ as selectActiveTeam,mW as seedDefaultRoles,T$ as revokeTokenById,y$ as revokeToken,R$ as revokeRefreshToken,gW as revokePermissionFromRole,u1 as revokePermission,w$ as revokeOtherTokens,h$ as revokeClient,j0 as revokeAllTokens,Y1 as revokeAllRefreshTokens,bW as revokeAllPermissions,f3 as resolveTeamContext,FZ as resolveAuthenticatedUser,I3 as resolveAuthenticatedTeamId,VZ as resolveAuthenticatedMembership,rW as resendVerificationEmail,k1 as removeRole,IW as removeAllRoles,PW as registerGates,l2 as register,E$ as refreshToken,$3 as refresh,O0 as policy,O2 as platformAuthenticatorIsAvailable,w2 as passwordResets,w as parseScopes,R1 as none,r2 as name,e2 as logout,$Z as isTwoFactorEnabled,d as isIssuedBeforePasswordChange,$$ as isEmailVerified,s2 as isAuthenticated,K3 as inspectUser,W0 as inspect,G3 as initializeAuthorization,o2 as id,h1 as hasRole,y1 as hasPolicy,d1 as hasPermission,p1 as hasAnyRole,n1 as hasAnyPermission,m1 as hasAllRoles,i1 as hasAllPermissions,N1 as has,kW as givePermissionToRole,c1 as givePermission,Q0 as getUserRoles,z0 as getUserPermissions,sZ as getUserPasskeys,$W as getUserPasskey,Z$ as getTwoFactorState,t1 as getRolePermissions,A1 as getPolicyFor,s as getPasswordChangedAt,t2 as getCurrentUser,yW as getAllRoles,fW as getAllPermissions,Q$ as getActiveTeamPreference,B1 as generateTwoFactorUri,gZ as generateTwoFactorToken,WZ as generateTwoFactorSetup,g0 as generateTwoFactorSecret,G4 as generateTOTPSecret,J4 as generateTOTP,G2 as generateRegistrationOptions,X2 as generateAuthenticationOptions,N0 as flushRbacCache,w1 as flush,G1 as findToken,b as findRole,u as findPermission,k$ as findClient,GZ as enableTwoFactor,a2 as email,CW as discoverPolicies,XZ as disableTwoFactor,x1 as denies,NW as deleteRole,I$ as deleteRevokedTokens,N$ as deleteRevokedRefreshTokens,wW as deletePermission,f$ as deleteExpiredTokens,A$ as deleteExpiredRefreshTokens,P1 as define,n as currentAccessToken,KZ as createTwoFactorChallenge,w0 as createToken,r0 as createRole,dZ as createPersonalAccessClient,TW as createPermission,g$ as createClient,_W as createBqbRbacStore,Z2 as consumeWebAuthnChallenge,LZ as consumeTwoFactorChallenge,QZ as consumePendingTwoFactorSecret,b$ as clients,w3 as clearActiveTeamCookie,MW as check,S0 as cannot,v0 as can,T3 as buildActiveTeamCookie,B2 as browserSupportsWebAuthnAutofill,F2 as browserSupportsWebAuthn,v1 as before,RW as authorizeUser,x0 as authorize,F0 as authUser,tZ as authMiddlewareHandler,e$ as authMiddleware,b1 as assignRole,_0 as any,E1 as allows,E0 as all,S1 as after,T1 as abilities,E3 as TwoFactor,C2 as SessionAuth,F3 as Rbac,k as RateLimiter,f1 as Gate,q3 as EmailVerification,o1 as DEFAULT_ROLE_PACKS,qW as BasePolicy,q as AuthorizationResponse,B0 as AuthorizationException,R as Auth,s0 as ACTIVE_TEAM_COOKIE};
165
+ This link expires in ${J} minutes.`})}}async function hW($,W){let Z=await i.selectFrom("email_verifications").where("user_id","=",$).selectAll().executeTakeFirst();if(!Z)return{success:!1,message:"No verification request found. Please request a new verification email."};let J=new Date(Z.expires_at);if(new Date>J)return await i.deleteFrom("email_verifications").where("user_id","=",$).execute(),{success:!1,message:"Verification link has expired. Please request a new one."};if(!bW($,W,Z.token))return{success:!1,message:"Invalid verification link."};return await i.updateTable("users").set({email_verified_at:new Date().toISOString()}).where("id","=",$).executeTakeFirst(),await i.deleteFrom("email_verifications").where("user_id","=",$).execute(),{success:!0,message:"Email verified successfully."}}async function pW($){if(l1($))return{success:!1,message:"Email is already verified."};let W=await i.selectFrom("email_verifications").where("user_id","=",$.id).selectAll().executeTakeFirst();if(W){let Z=new Date(W.created_at),J=(Date.now()-Z.getTime())/1000;if(J<60)return{success:!1,message:`Please wait ${Math.ceil(60-J)} seconds before requesting another verification email.`}}return await d1($),{success:!0,message:"Verification email sent."}}var L3={isVerified:l1,send:d1,verify:hW,resend:pW};import{randomBytes as mW}from"crypto";import{db as y}from"@stacksjs/database";var cW=300;async function n1($){let W=await y.selectFrom("users").where("id","=",$).select(["two_factor_secret","two_factor_enabled"]).executeTakeFirst();return{secret:W?.two_factor_secret??null,enabled:Boolean(W?.two_factor_enabled)}}function uW($){return Boolean($.two_factor_enabled)}function lW($,W){let Z=b0(),J=Q1($,W,Z);return{secret:Z,uri:J}}var dW=600;async function nW($,W,Z=dW){let J=new Date(Date.now()+Z*1000).toISOString();await y.deleteFrom("two_factor_pending_secrets").where("user_id","=",$).execute(),await y.insertInto("two_factor_pending_secrets").values({user_id:$,secret:W,expires_at:J}).execute()}async function iW($){let W=await y.selectFrom("two_factor_pending_secrets").where("user_id","=",$).selectAll().executeTakeFirst();if(!W)return null;await y.deleteFrom("two_factor_pending_secrets").where("user_id","=",$).execute();let Z=W.expires_at?new Date(String(W.expires_at)).getTime():0;if(Date.now()>Z)return null;return String(W.secret)}async function tW($,W,Z){if(!await k0(Z,W))return!1;return await y.updateTable("users").set({two_factor_secret:W,two_factor_enabled:!0}).where("id","=",$).executeTakeFirst(),!0}async function oW($){await y.updateTable("users").set({two_factor_secret:null,two_factor_enabled:!1}).where("id","=",$).executeTakeFirst()}async function aW($,W){let{secret:Z,enabled:J}=await n1($);if(!J||!Z)return!1;return k0(W,Z)}async function rW($,W=cW){let Z=mW(32).toString("hex"),J=new Date(Date.now()+W*1000).toISOString();return await y.deleteFrom("two_factor_challenges").where("user_id","=",$).execute(),await y.insertInto("two_factor_challenges").values({id:Z,user_id:$,expires_at:J}).execute(),Z}async function sW($){let W=await y.selectFrom("two_factor_challenges").where("id","=",$).selectAll().executeTakeFirst();if(!W)return null;await y.deleteFrom("two_factor_challenges").where("id","=",$).execute();let Z=W.expires_at?new Date(String(W.expires_at)).getTime():0;if(Date.now()>Z)return null;return Number(W.user_id)}var _3={isEnabled:uW,getState:n1,generateSetup:lW,stashPendingSecret:nW,consumePendingSecret:iW,enable:tW,disable:oW,verifyLoginCode:aW,createChallenge:rW,consumeChallenge:sW};import{config as c}from"@stacksjs/config";import{db as A0}from"@stacksjs/database";var l0="active_team";function i1($){let W=$.rolePriority??{owner:0,admin:1},Z=[...$.memberships??[]].sort((G,X)=>(W[G.role??""]??2)-(W[X.role??""]??2)),J=$.activeTeamId==null?null:Number($.activeTeamId);if(J!=null&&Number.isFinite(J)){let G=Z.find((X)=>Number(X.team_id)===J);if(G)return{teamId:J,role:G.role??null};if($.allowAnyTeam)return{teamId:J,role:"admin"}}let Q=Z[0];return Q?{teamId:Number(Q.team_id),role:Q.role??null}:{teamId:null,role:null}}function t1($){let W=$.cookies?.get(l0);if(!W)return null;let Z=Number(W);return Number.isFinite(Z)&&Z>0?Z:null}function U3($,W={}){let Z=Math.max(0,Math.floor(W.maxAgeSeconds??31536000)),J=[`${l0}=${encodeURIComponent(String($))}`,"Path=/","HttpOnly","SameSite=Lax",`Max-Age=${Z}`];if(W.secure)J.push("Secure");return J.join("; ")}function q3(){return`${l0}=; Path=/; HttpOnly; SameSite=Lax; Max-Age=0`}async function eW($){let W=await $Z($);if(!W?.id)return null;let Z=await A0.selectFrom("team_members").where("user_id","=",W.id).where("status","=","active").select(["team_id","role"]).execute();if(Z.length===0)return null;let J=i1({memberships:Z.map((Q)=>({team_id:Number(Q.team_id),role:String(Q.role)})),activeTeamId:t1($)});return J.teamId!=null?{teamId:J.teamId,role:J.role??String(Z[0].role)}:null}async function C3($,W={}){let Z={user:null,teamId:null,role:null,teams:[],activeTeamId:null},J=c.auth?.default||"api",G=(c.auth?.guards?.[J]?.driver||"token")==="session"?await o1($):await a1($);if(!G?.id)return Z;let X=await A0.selectFrom("team_members").where("user_id","=",G.id).where("status","=","active").select(["team_id","role"]).execute(),K=W.allowAnyTeam?!!W.allowAnyTeam(G):!1,Y=t1($),L=i1({memberships:X.map((F)=>({team_id:Number(F.team_id),role:String(F.role)})),activeTeamId:Y,allowAnyTeam:K}),O=new Map(X.map((F)=>[Number(F.team_id),String(F.role)])),_=[];if(K)_=await A0.selectFrom("teams").select(["id","name"]).execute();else{let F=[...O.keys()];_=F.length?await A0.selectFrom("teams").whereIn("id",F).select(["id","name"]).execute():[]}let E=_.map((F)=>({id:Number(F.id),name:String(F.name),role:O.get(Number(F.id))||"viewer"})).sort((F,j)=>F.name.localeCompare(j.name));return{user:G,teamId:L.teamId,role:L.role,teams:E,activeTeamId:Y}}async function P3($){let W=await eW($);return W?W.teamId:null}async function $Z($){let W=c.auth?.default||"api",Q=((c.auth?.guards?.[W]||{driver:"token"}).driver||"token")==="session"?await o1($):await a1($);return Q?.id?Q:void 0}async function o1($){let W=$.cookies?.get("session_id");if(!W)return;return p0(W)}async function a1($){let W=c.auth?.defaultTokenName||"auth-token",Z=(typeof $.bearerToken==="function"?$.bearerToken():void 0)??$.cookies?.get(W);if(!Z)return;return x.getUserFromToken(Z)}export{yW as withRbac,e2 as withAuthorization,aW as verifyTwoFactorLoginCode,k0 as verifyTwoFactorCode,o3 as verifyTOTP,aZ as verifyRegistrationResponse,hW as verifyEmail,rZ as verifyAuthenticationResponse,j$ as validateRefreshToken,_W as userCannot,zW as userCanAny,DW as userCanAll,OW as userCan,cZ as updatePasskeyCounter,r3 as totpKeyUri,V$ as tokens,B$ as tokenCant,_$ as tokenCanAny,O$ as tokenCanAll,s0 as tokenCan,z$ as tokenAbilities,F$ as token,A1 as syncRoles,AW as syncRolePermissions,I1 as syncPermissions,lZ as storeWebAuthnChallenge,nW as stashPendingTwoFactorSecret,sZ as startRegistration,eZ as startAuthentication,HW as setRbacStore,uZ as setCurrentRegistrationOptions,p0 as sessionUser,e$ as sessionRefresh,r$ as sessionLogout,a$ as sessionLogin,h0 as sessionDestroyAll,s$ as sessionCheck,d1 as sendVerificationEmail,i1 as selectActiveTeam,l3 as seedDefaultRoles,C$ as revokeTokenById,q$ as revokeToken,H$ as revokeRefreshToken,RW as revokePermissionFromRole,f1 as revokePermission,P$ as revokeOtherTokens,A$ as revokeClient,z0 as revokeAllTokens,e0 as revokeAllRefreshTokens,SW as revokeAllPermissions,C3 as resolveTeamContext,$Z as resolveAuthenticatedUser,P3 as resolveAuthenticatedTeamId,eW as resolveAuthenticatedMembership,pW as resendVerificationEmail,R1 as removeRole,EW as removeAllRoles,BW as registerGates,f2 as register,D$ as refreshToken,l2 as refresh,F0 as policy,Z2 as platformAuthenticatorIsAvailable,C2 as passwordResets,w as parseScopes,M1 as none,m2 as name,u2 as logout,uW as isTwoFactorEnabled,u as isIssuedBeforePasswordChange,l1 as isEmailVerified,c2 as isAuthenticated,s2 as inspectUser,e as inspect,o2 as initializeAuthorization,h2 as id,y1 as hasRole,C1 as hasPolicy,b1 as hasPermission,N1 as hasAnyRole,k1 as hasAnyPermission,w1 as hasAllRoles,g1 as hasAllPermissions,q1 as has,xW as givePermissionToRole,T1 as givePermission,Z0 as getUserRoles,O0 as getUserPermissions,mZ as getUserPasskeys,l$ as getUserPasskey,n1 as getTwoFactorState,h1 as getRolePermissions,U1 as getPolicyFor,a as getPasswordChangedAt,g2 as getCurrentUser,qW as getAllRoles,vW as getAllPermissions,t1 as getActiveTeamPreference,Q1 as generateTwoFactorUri,xZ as generateTwoFactorToken,lW as generateTwoFactorSetup,b0 as generateTwoFactorSecret,a3 as generateTOTPSecret,t3 as generateTOTP,tZ as generateRegistrationOptions,oZ as generateAuthenticationOptions,R0 as flushRbacCache,v1 as flush,r0 as findToken,p as findRole,m as findPermission,x$ as findClient,tW as enableTwoFactor,p2 as email,FW as discoverPolicies,oW as disableTwoFactor,H1 as denies,UW as deleteRole,E$ as deleteRevokedTokens,U$ as deleteRevokedRefreshTokens,PW as deletePermission,v$ as deleteExpiredTokens,M$ as deleteExpiredRefreshTokens,_1 as define,l as currentAccessToken,rW as createTwoFactorChallenge,N0 as createToken,MW as createRole,fZ as createPersonalAccessClient,CW as createPermission,R$ as createClient,m3 as createBqbRbacStore,dZ as consumeWebAuthnChallenge,sW as consumeTwoFactorChallenge,iW as consumePendingTwoFactorSecret,S$ as clients,q3 as clearActiveTeamCookie,KW as check,P0 as cannot,C0 as can,U3 as buildActiveTeamCookie,W2 as browserSupportsWebAuthnAutofill,$2 as browserSupportsWebAuthn,z1 as before,jW as authorizeUser,E0 as authorize,L0 as authUser,kZ as authMiddlewareHandler,u$ as authMiddleware,x1 as assignRole,B0 as any,j1 as allows,v0 as all,D1 as after,P1 as abilities,_3 as TwoFactor,F2 as SessionAuth,W3 as Rbac,f as RateLimiter,E1 as Gate,L3 as EmailVerification,u3 as DEFAULT_ROLE_PACKS,VW as BasePolicy,U as AuthorizationResponse,V0 as AuthorizationException,x as Auth,l0 as ACTIVE_TEAM_COOKIE};
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@stacksjs/auth",
3
3
  "type": "module",
4
- "version": "0.70.83",
4
+ "sideEffects": false,
5
+ "version": "0.70.85",
5
6
  "description": "A more simplistic way to authenticate.",
6
7
  "author": "Chris Breuer",
7
8
  "contributors": [
@@ -54,7 +55,7 @@
54
55
  },
55
56
  "devDependencies": {
56
57
  "better-dx": "^0.2.16",
57
- "@stacksjs/error-handling": "0.70.83",
58
- "@stacksjs/router": "0.70.83"
58
+ "@stacksjs/error-handling": "0.70.85",
59
+ "@stacksjs/router": "0.70.85"
59
60
  }
60
61
  }