@cauth/core 0.0.1 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index.d.cts → index.d.ts} +18 -14
- package/dist/index.js +1 -0
- package/package.json +3 -3
- package/dist/index.cjs +0 -1
|
@@ -194,33 +194,37 @@ type AuthGuardDeps = {
|
|
|
194
194
|
tokens: _CAuth<any>['Tokens'];
|
|
195
195
|
roles?: Array<string>;
|
|
196
196
|
};
|
|
197
|
-
|
|
197
|
+
/**
|
|
198
|
+
* Generic RoutesContract
|
|
199
|
+
* THandler is generic, defaults to any function
|
|
200
|
+
*/
|
|
201
|
+
interface RoutesContract<THandler extends (...args: any[]) => any = (...args: any[]) => any> {
|
|
198
202
|
Login({
|
|
199
203
|
...config
|
|
200
|
-
}: RouteDeps):
|
|
204
|
+
}: RouteDeps): THandler;
|
|
201
205
|
Register({
|
|
202
206
|
...config
|
|
203
|
-
}: RouteDeps):
|
|
207
|
+
}: RouteDeps): THandler;
|
|
204
208
|
Logout({
|
|
205
209
|
...config
|
|
206
|
-
}: RouteDeps):
|
|
210
|
+
}: RouteDeps): THandler;
|
|
207
211
|
Guard({
|
|
208
212
|
...config
|
|
209
|
-
}: AuthGuardDeps):
|
|
213
|
+
}: AuthGuardDeps): THandler;
|
|
210
214
|
Refresh({
|
|
211
215
|
...config
|
|
212
|
-
}: AuthGuardDeps):
|
|
216
|
+
}: AuthGuardDeps): THandler;
|
|
213
217
|
ChangePassword({
|
|
214
218
|
...config
|
|
215
219
|
}: RouteDeps & {
|
|
216
220
|
userId: string;
|
|
217
|
-
}):
|
|
221
|
+
}): THandler;
|
|
218
222
|
}
|
|
219
223
|
//#endregion
|
|
220
224
|
//#region src/types/config.t.d.ts
|
|
221
225
|
declare const CAuthOptionsSchema: z$1.ZodObject<{
|
|
222
226
|
dbContractor: z$1.ZodCustom<DatabaseContract, DatabaseContract>;
|
|
223
|
-
routeContractor: z$1.ZodCustom<RoutesContract
|
|
227
|
+
routeContractor: z$1.ZodCustom<RoutesContract<(...args: any[]) => any>, RoutesContract<(...args: any[]) => any>>;
|
|
224
228
|
roles: z$1.ZodArray<z$1.ZodString>;
|
|
225
229
|
jwtConfig: z$1.ZodObject<{
|
|
226
230
|
refreshTokenSecret: z$1.ZodString;
|
|
@@ -282,13 +286,13 @@ declare class _CAuth<T extends string[]> {
|
|
|
282
286
|
*
|
|
283
287
|
* @default undefined
|
|
284
288
|
*/
|
|
285
|
-
Guard: (roles?: Array<T[number]>) => any;
|
|
289
|
+
Guard: (roles?: Array<T[number]>) => (...args: any[]) => any;
|
|
286
290
|
Routes: {
|
|
287
|
-
Register: () => any;
|
|
288
|
-
Login: () => any;
|
|
289
|
-
Logout: () => any;
|
|
290
|
-
Refresh: () => any;
|
|
291
|
-
ChangePassword: (userId: string) => any;
|
|
291
|
+
Register: () => (...args: any[]) => any;
|
|
292
|
+
Login: () => (...args: any[]) => any;
|
|
293
|
+
Logout: () => (...args: any[]) => any;
|
|
294
|
+
Refresh: () => (...args: any[]) => any;
|
|
295
|
+
ChangePassword: (userId: string) => (...args: any[]) => any;
|
|
292
296
|
};
|
|
293
297
|
FN: {
|
|
294
298
|
Login: ({
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import e,{z as t}from"zod";import{parsePhoneNumberFromString as n}from"libphonenumber-js";import r from"bcrypt";import i from"jsonwebtoken";var a=class{static ValidationError=`validation-error`;static CredentialError=`credential-error`;static UnKnownError=`unknown-error`;static InvalidDataError=`invalid-data-error`},o=class{static ServerError=`internal-server-error`;static ServerErrorMessage=`Internal server error. We are working to fix this, please try again later`;static InvalidToken=`invalid-token`;static InvalidTokenMessage=`Invalid Token`;static ForbiddenResource=`forbidden-resource`;static ForbiddenResourceMessage=`You don't have sufficient permission for this action`;static InvalidOtp=`invalid-otp`;static InvalidOtpMessage=`Invalid Otp. Please check and try again`;static CredentialMismatch=`credential-mismatch`;static CredentialMismatchMessage=`Credential mismatch. Please check your credentials and try again.`;static InvalidData=`invalid-data`;static InvalidDataMessage=e=>`Invalid Body: ${e}`;static AccountNotFound=`account-not-found`;static AccountNotFoundMessage=`Account not found`;static InvalidRole=`invalid-role`;static InvalidRoleMessage=e=>`Role is invalid, please use one of the following roles: ${e.join(`, `)}`;static InvalidRefreshToken=`invalid-refresh-token`;static InvalidRefreshTokenMessage=`Invalid refresh token`;static DuplicateAccount=`account-already-exists`;static DuplicateAccountMessage=`Account with this credentials already exists`},s=class extends Error{code;static type=a.CredentialError;constructor(){super(o.CredentialMismatchMessage),this.code=o.CredentialMismatch,this.name=`CredentialMismatch`}},c=class extends Error{code;static type=a.ValidationError;constructor(e){super(o.InvalidDataMessage(e)),this.code=o.InvalidData,this.name=`InvalidDataError`}},l=class extends Error{code;static type=a.InvalidDataError;constructor(){super(o.AccountNotFoundMessage),this.code=o.AccountNotFound,this.name=`AccountNotFoundError`}},u=class extends Error{code;static type=a.ValidationError;constructor(e){super(o.InvalidRoleMessage(e)),this.code=o.InvalidRole,this.name=`InvalidRoleError`}},d=class extends Error{code;static type=a.ValidationError;constructor(){super(o.InvalidRefreshTokenMessage),this.code=o.InvalidRefreshToken,this.name=`InvalidRefreshTokenError`}},f=class extends Error{code;static type=a.ValidationError;constructor(){super(o.DuplicateAccountMessage),this.code=o.DuplicateAccount,this.name=`DuplicateAccountError`}},p=class extends Error{code;static type=a.ValidationError;constructor(){super(o.InvalidOtpMessage),this.code=o.InvalidOtp,this.name=`InvalidOTPCode`}},m=class{static LoginPurpose=`LOGIN`;static ResetPasswordPurpose=`RESET_PASSWORD`;static ActionPurpose=`ACTION`};const h=t.string().trim().refine(e=>{let t=n(e);return!!t&&t.isValid()},{message:`Invalid phone number`}).transform(e=>n(e)?.format(`E.164`)??e),g=t.object({email:t.email(),phoneNumber:t.never().optional(),password:t.string().min(6)}),_=t.object({phoneNumber:h,email:t.never().optional(),password:t.string().min(6)}),v=t.union([g,_]).superRefine((e,n)=>{e.email&&e.phoneNumber&&n.addIssue({code:t.ZodIssueCode.custom,message:`Provide either email or phoneNumber`,path:[`email`,`phoneNumber`]})}),y=t.object({phoneNumber:h.optional(),email:t.email().optional(),role:t.string(),password:t.string()}).superRefine((e,n)=>{!e.email&&!e.phoneNumber&&n.addIssue({code:t.ZodIssueCode.custom,message:`Provide either email or phoneNumber`,path:[`email`,`phoneNumber`]})}),b=t.object({refreshToken:t.string()}),x=t.object({refreshToken:t.string()}),S=t.object({accountId:t.string(),oldPassword:t.string(),newPassword:t.string()});function C(e){return`${e?.error?.issues[0].path}: ${e?.error?.issues[0].message}`}function w(e){return{success:!0,value:e}}function T(...e){return{success:!1,errors:e}}async function E({config:e},{...t}){let n=v.safeParse({email:t.email,phoneNumber:t.phoneNumber,password:``});if(!n.success)return T({type:c.type,error:new c(C(n))});let i=await e.dbContractor.findAccountWithCredential({phoneNumber:t.phoneNumber,email:t.email});if(!i||t.usePassword&&!await r.compare(String(t.password),String(i?.passwordHash)))return T({type:s.type,error:new s});let a=await e.dbContractor.createOTP({config:e},{id:i.id,purpose:t.otpPurpose});return w({id:i.id,code:a.code})}async function D({config:e,tokens:t},{...n}){let r=v.safeParse({email:n.email,phoneNumber:n.phoneNumber,password:``});if(!r.success)return T({type:c.type,error:new c(C(r))});let i=await e.dbContractor.findAccountWithCredential({email:n.email,phoneNumber:n.phoneNumber});if(!i)return T({type:s.type,error:new s});if(!(await e.dbContractor.verifyOTP({id:i.id,code:n.code,purpose:m.LoginPurpose})).isValid)return T({type:p.type,error:new p});let a=await t.GenerateTokenPairs({id:i.id,role:i.role});return await e.dbContractor.updateAccountLogin({id:i.id,refreshToken:a.refreshToken}),delete i.passwordHash,delete i.refreshTokens,w({account:i,tokens:a})}async function O({config:e},{...t}){return await e.dbContractor.verifyOTP({id:t.id,code:t.code,purpose:t.otpPurpose})}async function k({config:e},{...t}){let n=S.safeParse(t);if(!n.success)return T({type:c.type,error:new c(C(n))});let i=await e.dbContractor.findAccountById({id:t.accountId});if(!i)return T({type:l.type,error:new l});if(!r.compare(t.oldPassword,String(i.passwordHash)))return T({type:s.type,error:new s});let a=await r.hash(t.newPassword,10);return await e.dbContractor.updateAccount({id:i.id,data:{passwordHash:a}}),w({})}async function A({config:e,tokens:t},{...n}){let i=v.safeParse(n);if(!i.success)return T({type:c.type,error:new c(C(i))});let a=await e.dbContractor.findAccountWithCredential({email:n.email,phoneNumber:n.phoneNumber});if(!a||!await r.compare(String(n.password),String(a?.passwordHash)))return T({type:s.type,error:new s});let o=await t.GenerateTokenPairs({id:a.id,role:a.role});return await e.dbContractor.updateAccountLogin({id:a.id,refreshToken:o.refreshToken}),delete a.passwordHash,delete a.refreshTokens,w({account:a,tokens:o})}async function j(e){try{return{data:await e,error:null}}catch(e){return{data:null,error:e}}}async function M({config:e,tokens:t},{...n}){let r=x.safeParse(n);if(!r.success)return T({type:c.type,error:new c(C(r))});let i=await j(t.VerifyRefreshToken(n.refreshToken));return i.error||!i?T({type:d.type,error:new d}):(await e.dbContractor.removeAndAddRefreshToken({id:String(i.data?.id),refreshToken:n.refreshToken}),w({}))}async function N({config:e,tokens:t},{...n}){let r=b.safeParse(n);if(!r.success)return T({type:c.type,error:new c(C(r))});let i=await j(t.VerifyRefreshToken(n.refreshToken));if(i.error)return T({type:d.type,error:new d});let a=await e.dbContractor.findAccountById({id:String(i.data?.id)});if(!a)return T({type:l.type,error:new l});if(!a?.refreshTokens?.includes(n.refreshToken))return T({type:d.type,error:new d});let o=await t.GenerateTokenPairs({id:a.id,role:a.role});return await e.dbContractor.removeAndAddRefreshToken({id:a.id,refreshToken:n.refreshToken,newRefreshToken:o.refreshToken}),delete a.refreshTokens,delete a.passwordHash,w({account:a,tokens:o})}async function P({config:e,tokens:t},{...n}){let i=y.safeParse(n);if(!i.success)return T({type:c.type,error:new c(C(i))});if(!e.roles?.includes(n.role))return T({type:u.type,error:new u(e.roles)});if(await e.dbContractor.findAccountWithCredential({email:n.email,phoneNumber:n.phoneNumber}))return T({type:f.type,error:new f});let a=await r.hash(n.password,10),o=await e.dbContractor.createAccount({data:{email:n.email,phoneNumber:n.phoneNumber,passwordHash:a,role:n.role,lastLogin:new Date}}),s=await t.GenerateTokenPairs({id:o.id,role:o.role});return await e.dbContractor.updateAccountLogin({id:o.id,refreshToken:s.refreshToken}),w({account:o,tokens:s})}async function F({...e}){return i.sign(e.payload,e.config.jwtConfig.accessTokenSecret,{expiresIn:e.config.jwtConfig?.accessTokenLifeSpan??`15m`})}async function I({...e}){return i.sign(e.payload,e.config.jwtConfig.refreshTokenSecret,{expiresIn:e.config.jwtConfig?.refreshTokenLifeSpan??`30d`})}async function L({...e}){return{accessToken:i.sign(e.payload,e.config.jwtConfig.accessTokenSecret,{expiresIn:e.config.jwtConfig?.accessTokenLifeSpan??`15m`}),refreshToken:i.sign(e.payload,e.config.jwtConfig.refreshTokenSecret,{expiresIn:e.config.jwtConfig?.refreshTokenLifeSpan??`30d`})}}async function R({...e}){let t=i.verify(e.token,e.config.jwtConfig.refreshTokenSecret);return t instanceof String?null:t}async function z({...e}){let t=i.verify(e.token,e.config.jwtConfig.accessTokenSecret);return t instanceof String?null:t}const B=e.custom(()=>!0,{message:`Invalid dbContractor: must implement Database Contract interface`}),V=e.custom(()=>!0,{message:`Invalid routeContractor: must implement RoutesContract interface`}),H=e.custom(),U=e.object({dbContractor:B,routeContractor:V,roles:e.array(e.string()).min(1),jwtConfig:e.object({refreshTokenSecret:e.string(),accessTokenSecret:e.string(),accessTokenLifeSpan:H.optional(),refreshTokenLifeSpan:H.optional()}),otpConfig:e.object({expiresIn:e.number().optional(),length:e.number().min(4).max(8).optional()})});var W=class{#config;constructor(e){if(!U.safeParse(e).success)throw Error(`❌ Failed to initiate CAuth. You provided an invalid config!`);this.#config=e}get RoleType(){return null}Guard=e=>this.#config.routeContractor.Guard({config:this.#config,tokens:this.Tokens,roles:e});Routes={Register:()=>this.#config.routeContractor.Register({config:this.#config,tokens:this.Tokens}),Login:()=>this.#config.routeContractor.Login({config:this.#config,tokens:this.Tokens}),Logout:()=>this.#config.routeContractor.Logout({config:this.#config,tokens:this.Tokens}),Refresh:()=>this.#config.routeContractor.Refresh({config:this.#config,tokens:this.Tokens}),ChangePassword:e=>this.#config.routeContractor.ChangePassword({config:this.#config,tokens:this.Tokens,userId:e})};FN={Login:({...e})=>A({config:this.#config,tokens:this.Tokens},e),Register:({...e})=>P({config:this.#config,tokens:this.Tokens},e),Logout:({...e})=>M({config:this.#config,tokens:this.Tokens},e),Refresh:({...e})=>N({config:this.#config,tokens:this.Tokens},e),ChangePassword:({...e})=>k({config:this.#config,tokens:this.Tokens},e),RequestOTPCode:({...e})=>E({config:this.#config,tokens:this.Tokens},e),LoginWithOTP:({...e})=>D({config:this.#config,tokens:this.Tokens},{...e}),VerifyOTP:({...e})=>O({config:this.#config,tokens:this.Tokens},e)};Tokens={GenerateRefreshToken:e=>I({payload:e,config:this.#config}),GenerateAccessToken:e=>F({payload:e,config:this.#config}),GenerateTokenPairs:e=>L({payload:e,config:this.#config}),VerifyRefreshToken:e=>R({token:e,config:this.#config}),VerifyAccessToken:e=>z({token:e,config:this.#config})}};function G(e){return new W(e)}export{l as AccountNotFoundError,G as CAuth,s as CredentialMismatchError,f as DuplicateAccountError,c as InvalidDataError,p as InvalidOTPCode,d as InvalidRefreshTokenError,u as InvalidRoleError};
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cauth/core",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "",
|
|
5
|
-
"main": "./dist/index.
|
|
6
|
-
"types": "./dist/index.d.
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"build": "tsdown",
|
package/dist/index.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));let c=require(`zod`);c=s(c);let l=require(`libphonenumber-js`);l=s(l);let u=require(`bcrypt`);u=s(u);let d=require(`jsonwebtoken`);d=s(d);var f=class{static ValidationError=`validation-error`;static CredentialError=`credential-error`;static UnKnownError=`unknown-error`;static InvalidDataError=`invalid-data-error`},p=class{static ServerError=`internal-server-error`;static ServerErrorMessage=`Internal server error. We are working to fix this, please try again later`;static InvalidToken=`invalid-token`;static InvalidTokenMessage=`Invalid Token`;static ForbiddenResource=`forbidden-resource`;static ForbiddenResourceMessage=`You don't have sufficient permission for this action`;static InvalidOtp=`invalid-otp`;static InvalidOtpMessage=`Invalid Otp. Please check and try again`;static CredentialMismatch=`credential-mismatch`;static CredentialMismatchMessage=`Credential mismatch. Please check your credentials and try again.`;static InvalidData=`invalid-data`;static InvalidDataMessage=e=>`Invalid Body: ${e}`;static AccountNotFound=`account-not-found`;static AccountNotFoundMessage=`Account not found`;static InvalidRole=`invalid-role`;static InvalidRoleMessage=e=>`Role is invalid, please use one of the following roles: ${e.join(`, `)}`;static InvalidRefreshToken=`invalid-refresh-token`;static InvalidRefreshTokenMessage=`Invalid refresh token`;static DuplicateAccount=`account-already-exists`;static DuplicateAccountMessage=`Account with this credentials already exists`},m=class extends Error{code;static type=f.CredentialError;constructor(){super(p.CredentialMismatchMessage),this.code=p.CredentialMismatch,this.name=`CredentialMismatch`}},h=class extends Error{code;static type=f.ValidationError;constructor(e){super(p.InvalidDataMessage(e)),this.code=p.InvalidData,this.name=`InvalidDataError`}},g=class extends Error{code;static type=f.InvalidDataError;constructor(){super(p.AccountNotFoundMessage),this.code=p.AccountNotFound,this.name=`AccountNotFoundError`}},_=class extends Error{code;static type=f.ValidationError;constructor(e){super(p.InvalidRoleMessage(e)),this.code=p.InvalidRole,this.name=`InvalidRoleError`}},v=class extends Error{code;static type=f.ValidationError;constructor(){super(p.InvalidRefreshTokenMessage),this.code=p.InvalidRefreshToken,this.name=`InvalidRefreshTokenError`}},y=class extends Error{code;static type=f.ValidationError;constructor(){super(p.DuplicateAccountMessage),this.code=p.DuplicateAccount,this.name=`DuplicateAccountError`}},b=class extends Error{code;static type=f.ValidationError;constructor(){super(p.InvalidOtpMessage),this.code=p.InvalidOtp,this.name=`InvalidOTPCode`}},x=class{static LoginPurpose=`LOGIN`;static ResetPasswordPurpose=`RESET_PASSWORD`;static ActionPurpose=`ACTION`};const S=c.z.string().trim().refine(e=>{let t=(0,l.parsePhoneNumberFromString)(e);return!!t&&t.isValid()},{message:`Invalid phone number`}).transform(e=>(0,l.parsePhoneNumberFromString)(e)?.format(`E.164`)??e),C=c.z.object({email:c.z.email(),phoneNumber:c.z.never().optional(),password:c.z.string().min(6)}),w=c.z.object({phoneNumber:S,email:c.z.never().optional(),password:c.z.string().min(6)}),T=c.z.union([C,w]).superRefine((e,t)=>{e.email&&e.phoneNumber&&t.addIssue({code:c.z.ZodIssueCode.custom,message:`Provide either email or phoneNumber`,path:[`email`,`phoneNumber`]})}),E=c.z.object({phoneNumber:S.optional(),email:c.z.email().optional(),role:c.z.string(),password:c.z.string()}),D=E.superRefine((e,t)=>{!e.email&&!e.phoneNumber&&t.addIssue({code:c.z.ZodIssueCode.custom,message:`Provide either email or phoneNumber`,path:[`email`,`phoneNumber`]})}),O=c.z.object({refreshToken:c.z.string()}),k=c.z.object({refreshToken:c.z.string()}),A=c.z.object({accountId:c.z.string(),oldPassword:c.z.string(),newPassword:c.z.string()});function j(e){return`${e?.error?.issues[0].path}: ${e?.error?.issues[0].message}`}function M(e){return{success:!0,value:e}}function N(...e){return{success:!1,errors:e}}async function P({config:e},{...t}){let n=T.safeParse({email:t.email,phoneNumber:t.phoneNumber,password:``});if(!n.success)return N({type:h.type,error:new h(j(n))});let r=await e.dbContractor.findAccountWithCredential({phoneNumber:t.phoneNumber,email:t.email});if(!r||t.usePassword&&!await u.default.compare(String(t.password),String(r?.passwordHash)))return N({type:m.type,error:new m});let i=await e.dbContractor.createOTP({config:e},{id:r.id,purpose:t.otpPurpose});return M({id:r.id,code:i.code})}async function F({config:e,tokens:t},{...n}){let r=T.safeParse({email:n.email,phoneNumber:n.phoneNumber,password:``});if(!r.success)return N({type:h.type,error:new h(j(r))});let i=await e.dbContractor.findAccountWithCredential({email:n.email,phoneNumber:n.phoneNumber});if(!i)return N({type:m.type,error:new m});if(!(await e.dbContractor.verifyOTP({id:i.id,code:n.code,purpose:x.LoginPurpose})).isValid)return N({type:b.type,error:new b});let a=await t.GenerateTokenPairs({id:i.id,role:i.role});return await e.dbContractor.updateAccountLogin({id:i.id,refreshToken:a.refreshToken}),delete i.passwordHash,delete i.refreshTokens,M({account:i,tokens:a})}async function I({config:e},{...t}){return await e.dbContractor.verifyOTP({id:t.id,code:t.code,purpose:t.otpPurpose})}async function L({config:e},{...t}){let n=A.safeParse(t);if(!n.success)return N({type:h.type,error:new h(j(n))});let r=await e.dbContractor.findAccountById({id:t.accountId});if(!r)return N({type:g.type,error:new g});if(!u.default.compare(t.oldPassword,String(r.passwordHash)))return N({type:m.type,error:new m});let i=await u.default.hash(t.newPassword,10);return await e.dbContractor.updateAccount({id:r.id,data:{passwordHash:i}}),M({})}async function R({config:e,tokens:t},{...n}){let r=T.safeParse(n);if(!r.success)return N({type:h.type,error:new h(j(r))});let i=await e.dbContractor.findAccountWithCredential({email:n.email,phoneNumber:n.phoneNumber});if(!i||!await u.default.compare(String(n.password),String(i?.passwordHash)))return N({type:m.type,error:new m});let a=await t.GenerateTokenPairs({id:i.id,role:i.role});return await e.dbContractor.updateAccountLogin({id:i.id,refreshToken:a.refreshToken}),delete i.passwordHash,delete i.refreshTokens,M({account:i,tokens:a})}async function z(e){try{return{data:await e,error:null}}catch(e){return{data:null,error:e}}}async function B({config:e,tokens:t},{...n}){let r=k.safeParse(n);if(!r.success)return N({type:h.type,error:new h(j(r))});let i=await z(t.VerifyRefreshToken(n.refreshToken));return i.error||!i?N({type:v.type,error:new v}):(await e.dbContractor.removeAndAddRefreshToken({id:String(i.data?.id),refreshToken:n.refreshToken}),M({}))}async function V({config:e,tokens:t},{...n}){let r=O.safeParse(n);if(!r.success)return N({type:h.type,error:new h(j(r))});let i=await z(t.VerifyRefreshToken(n.refreshToken));if(i.error)return N({type:v.type,error:new v});let a=await e.dbContractor.findAccountById({id:String(i.data?.id)});if(!a)return N({type:g.type,error:new g});if(!a?.refreshTokens?.includes(n.refreshToken))return N({type:v.type,error:new v});let o=await t.GenerateTokenPairs({id:a.id,role:a.role});return await e.dbContractor.removeAndAddRefreshToken({id:a.id,refreshToken:n.refreshToken,newRefreshToken:o.refreshToken}),delete a.refreshTokens,delete a.passwordHash,M({account:a,tokens:o})}async function H({config:e,tokens:t},{...n}){let r=D.safeParse(n);if(!r.success)return N({type:h.type,error:new h(j(r))});if(!e.roles?.includes(n.role))return N({type:_.type,error:new _(e.roles)});if(await e.dbContractor.findAccountWithCredential({email:n.email,phoneNumber:n.phoneNumber}))return N({type:y.type,error:new y});let i=await u.default.hash(n.password,10),a=await e.dbContractor.createAccount({data:{email:n.email,phoneNumber:n.phoneNumber,passwordHash:i,role:n.role,lastLogin:new Date}}),o=await t.GenerateTokenPairs({id:a.id,role:a.role});return await e.dbContractor.updateAccountLogin({id:a.id,refreshToken:o.refreshToken}),M({account:a,tokens:o})}async function U({...e}){return d.default.sign(e.payload,e.config.jwtConfig.accessTokenSecret,{expiresIn:e.config.jwtConfig?.accessTokenLifeSpan??`15m`})}async function W({...e}){return d.default.sign(e.payload,e.config.jwtConfig.refreshTokenSecret,{expiresIn:e.config.jwtConfig?.refreshTokenLifeSpan??`30d`})}async function G({...e}){return{accessToken:d.default.sign(e.payload,e.config.jwtConfig.accessTokenSecret,{expiresIn:e.config.jwtConfig?.accessTokenLifeSpan??`15m`}),refreshToken:d.default.sign(e.payload,e.config.jwtConfig.refreshTokenSecret,{expiresIn:e.config.jwtConfig?.refreshTokenLifeSpan??`30d`})}}async function K({...e}){let t=d.default.verify(e.token,e.config.jwtConfig.refreshTokenSecret);return t instanceof String?null:t}async function q({...e}){let t=d.default.verify(e.token,e.config.jwtConfig.accessTokenSecret);return t instanceof String?null:t}const J=c.default.custom(()=>!0,{message:`Invalid dbContractor: must implement Database Contract interface`}),Y=c.default.custom(()=>!0,{message:`Invalid routeContractor: must implement RoutesContract interface`}),X=c.default.custom(),Z=c.default.object({dbContractor:J,routeContractor:Y,roles:c.default.array(c.default.string()).min(1),jwtConfig:c.default.object({refreshTokenSecret:c.default.string(),accessTokenSecret:c.default.string(),accessTokenLifeSpan:X.optional(),refreshTokenLifeSpan:X.optional()}),otpConfig:c.default.object({expiresIn:c.default.number().optional(),length:c.default.number().min(4).max(8).optional()})});var Q=class{#config;constructor(e){if(!Z.safeParse(e).success)throw Error(`❌ Failed to initiate CAuth. You provided an invalid config!`);this.#config=e}get RoleType(){return null}Guard=e=>this.#config.routeContractor.Guard({config:this.#config,tokens:this.Tokens,roles:e});Routes={Register:()=>this.#config.routeContractor.Register({config:this.#config,tokens:this.Tokens}),Login:()=>this.#config.routeContractor.Login({config:this.#config,tokens:this.Tokens}),Logout:()=>this.#config.routeContractor.Logout({config:this.#config,tokens:this.Tokens}),Refresh:()=>this.#config.routeContractor.Refresh({config:this.#config,tokens:this.Tokens}),ChangePassword:e=>this.#config.routeContractor.ChangePassword({config:this.#config,tokens:this.Tokens,userId:e})};FN={Login:({...e})=>R({config:this.#config,tokens:this.Tokens},e),Register:({...e})=>H({config:this.#config,tokens:this.Tokens},e),Logout:({...e})=>B({config:this.#config,tokens:this.Tokens},e),Refresh:({...e})=>V({config:this.#config,tokens:this.Tokens},e),ChangePassword:({...e})=>L({config:this.#config,tokens:this.Tokens},e),RequestOTPCode:({...e})=>P({config:this.#config,tokens:this.Tokens},e),LoginWithOTP:({...e})=>F({config:this.#config,tokens:this.Tokens},{...e}),VerifyOTP:({...e})=>I({config:this.#config,tokens:this.Tokens},e)};Tokens={GenerateRefreshToken:e=>W({payload:e,config:this.#config}),GenerateAccessToken:e=>U({payload:e,config:this.#config}),GenerateTokenPairs:e=>G({payload:e,config:this.#config}),VerifyRefreshToken:e=>K({token:e,config:this.#config}),VerifyAccessToken:e=>q({token:e,config:this.#config})}};function $(e){return new Q(e)}exports.AccountNotFoundError=g,exports.CAuth=$,exports.CredentialMismatchError=m,exports.DuplicateAccountError=y,exports.InvalidDataError=h,exports.InvalidOTPCode=b,exports.InvalidRefreshTokenError=v,exports.InvalidRoleError=_;
|