@cauth/express 0.1.7 → 0.1.8

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 +3 -1
  2. package/package.json +1 -5
package/dist/index.js CHANGED
@@ -1 +1,3 @@
1
- import{z as e}from"zod";import{parsePhoneNumberFromString as t}from"libphonenumber-js";import n from"argon2-browser";import r from"node:crypto";var i=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`;static SchemaValidationError=`schema-validation`;static SchemaValidationMessage=`Your database error is not is sync with CAuth Spec`};async function a(e){try{return{data:await e,error:null}}catch(e){return{data:null,error:e}}}function o({tokens:e,config:t,roles:n}){return async(r,o,s)=>{try{let c=r.cookies?.accessToken;if(!c){let e=r.headers.authorization;e?.startsWith(`Bearer `)&&(c=e.split(` `)[1])}if(!c)return o.status(401).send({code:i.InvalidToken});let l=await a(e.VerifyAccessToken(c));return l.error||!l.data?o.status(401).send({code:i.InvalidToken}):n&&!n.includes(l.data.role)||!t.roles.includes(l.data.role)?o.status(403).send({code:i.ForbiddenResource,message:i.ForbiddenResourceMessage}):(r.cauth={id:l.data.id,role:l.data.role},s())}catch{return o.status(500).send({code:i.ServerError})}}}const s=e.string().trim().refine(e=>{let n=t(e);return!!n&&n.isValid()},{message:`Invalid phone number`}).transform(e=>t(e)?.format(`E.164`)??e),c=e.enum([`LOGIN`,`RESET_PASSWORD`,`ACTION`]),l=e.object({email:e.email(),phoneNumber:e.never().optional(),password:e.string().min(6).optional()}),u=e.object({phoneNumber:s,email:e.never().optional(),password:e.string().min(6).optional()}),d=e.union([l,u]).superRefine((t,n)=>{t.email&&t.phoneNumber&&n.addIssue({code:e.ZodIssueCode.custom,message:`Provide either email or phoneNumber`,path:[`email`,`phoneNumber`]})}),f=e.object({phoneNumber:s,email:e.never().optional(),code:e.string().min(4).max(8)}),p=e.object({email:e.email(),phoneNumber:e.never().optional(),code:e.string().min(4).max(8)});e.union([p,f]);const m=e.object({otpPurpose:c,usePassword:e.boolean().default(!1),password:e.string().optional()}),h=m.extend({phoneNumber:s,email:e.never().optional()}),g=m.extend({phoneNumber:e.never().optional(),email:e.string().email()});e.union([h,g]).refine(e=>e.usePassword?!!e.password:!e.password,{message:`Password required only if usePassword is true`,path:[`password`]});const _=e.object({phoneNumber:s.optional(),email:e.email().optional(),role:e.string(),password:e.string().optional()}).superRefine((t,n)=>{!t.email&&!t.phoneNumber&&n.addIssue({code:e.ZodIssueCode.custom,message:`Provide either email or phoneNumber`,path:[`email`,`phoneNumber`]})}),v=e.object({refreshToken:e.string()}),y=e.object({refreshToken:e.string()}),b=e.object({accountId:e.string(),oldPassword:e.string(),newPassword:e.string()});function x(e){return`${e?.error?.issues[0].path}: ${e?.error?.issues[0].message}`}var S=class{static ValidationError=`validation-error`;static CredentialError=`credential-error`;static UnKnownError=`unknown-error`;static InvalidDataError=`invalid-data-error`};const C={CredentialMismatchError:{type:S.CredentialError,message:i.CredentialMismatchMessage,code:i.CredentialMismatch,name:`CredentialMismatchError`},InvalidDataError:e=>({type:S.ValidationError,message:i.InvalidDataMessage(e),code:i.InvalidData,name:`InvalidDataError`}),AccountNotFoundError:{type:S.InvalidDataError,message:i.AccountNotFoundMessage,code:i.AccountNotFound,name:`AccountNotFoundError`},InvalidRoleError:e=>({type:S.ValidationError,message:i.InvalidRoleMessage(e),code:i.InvalidRole,name:`InvalidRoleError`}),InvalidRefreshTokenError:{type:S.ValidationError,message:i.InvalidRefreshTokenMessage,code:i.InvalidRefreshToken,name:`InvalidRefreshTokenError`},DuplicateAccountError:{type:S.ValidationError,message:i.DuplicateAccountMessage,code:i.DuplicateAccount,name:`DuplicateAccountError`},InvalidOTPCode:{type:S.ValidationError,message:i.InvalidOtpMessage,code:i.InvalidOtp,name:`InvalidOTPCode`},SchemaInvalidError:{type:S.ValidationError,message:i.SchemaValidationMessage,code:i.SchemaValidationError,name:`SchemaInvalidError`}};function w(e){return{success:!0,value:e}}function T(...e){return{success:!1,errors:e}}async function E({config:e},{...t}){let r=b.safeParse(t);if(!r.success)return T({error:C.InvalidDataError(x(r))});let i=await e.dbContractor.findAccountById({id:t.accountId});if(!i||!await n.verify({pass:String(t.oldPassword),encoded:String(i.passwordHash)}))return T({error:C.CredentialMismatchError});let a=await n.hash({pass:t.newPassword,salt:`salt123`});return await e.dbContractor.updateAccount({id:i.id,data:{passwordHash:a}}),w({})}function D({config:e,userId:t}){return async(n,r)=>{try{let a=await E({config:e},{accountId:t,oldPassword:n.body.oldPassword,newPassword:n.body.newPassword});if(!a.success){let e=a.errors[0].error,t=400;return e.code===i.InvalidRole||e.code===i.DuplicateAccount?t=409:e.code===i.ServerError&&(t=500),r.status(t).send({code:e.code,message:e.message})}return r.status(200).send({code:`password-changed`})}catch(e){return console.error(`ChangePassword error:`,e),r.status(500).send({code:i.ServerError})}}}async function O({config:e,tokens:t},{...r}){let i=d.safeParse(r);if(!i.success)return T({error:C.InvalidDataError(x(i))});let a=await e.dbContractor.findAccountWithCredential({email:r.email,phoneNumber:r.phoneNumber});if(!a||!await n.verify({pass:String(r.password),encoded:String(a?.passwordHash)}))return T({error:C.CredentialMismatchError});let o=await t.GenerateTokenPairs({id:a.id,role:a.role});return await e.dbContractor.updateAccountLogin({id:a.id,refreshToken:o.refreshToken,config:e}),delete a.passwordHash,delete a.refreshTokens,w({account:a,tokens:o})}function k({config:e,tokens:t}){return async(n,r)=>{try{let a=await O({config:e,tokens:t},n.body);if(!a.success){let e=a.errors[0].error,t=400;return e.code===i.CredentialMismatch?t=409:e.code===i.ServerError&&(t=500),r.status(t).send({code:e.code,message:e.message})}return r.status(200).send(a.value)}catch{return r.status(500).send({code:i.ServerError})}}}async function A({config:e,tokens:t},{...n}){let r=y.safeParse(n);if(!r.success)return T({error:C.InvalidDataError(x(r))});let i=await a(t.VerifyRefreshToken(n.refreshToken));return i.error||!i?T({error:C.InvalidRefreshTokenError}):(await e.dbContractor.removeAndAddRefreshToken({id:String(i.data?.id),refreshToken:n.refreshToken}),w({}))}function j({config:e,tokens:t}){return async(n,r)=>{try{let a=await A({config:e,tokens:t},{refreshToken:n.body.refreshToken});if(!a.success){let e=a.errors[0].error,t=400;return e.code===i.InvalidRole||e.code===i.DuplicateAccount?t=409:e.code===i.ServerError&&(t=500),r.status(t).send({code:e.code,message:e.message})}return r.status(200).send({code:`logged-out`})}catch(e){return console.error(`Logout error:`,e),r.status(500).send({code:`server-error`})}}}function M({token:e,refreshTokenSecret:t}){return r.createHmac(`sha256`,t).update(e).digest(`hex`)}function N({incomingToken:e,storedHash:t,refreshTokenSecret:n}){let i=M({token:e,refreshTokenSecret:n});return r.timingSafeEqual(Buffer.from(i),Buffer.from(t))}async function P({config:e,tokens:t},{...n}){let r=v.safeParse(n);if(!r.success)return T({error:C.InvalidDataError(x(r))});let i=await a(t.VerifyRefreshToken(n.refreshToken));if(i.error)return T({error:C.InvalidRefreshTokenError});let o=await e.dbContractor.findAccountById({id:String(i.data?.id)});if(!o)return T({error:C.AccountNotFoundError});if(!o?.refreshTokens?.some(t=>N({incomingToken:n.refreshToken,storedHash:t.token,refreshTokenSecret:e.jwtConfig.refreshTokenSecret})))return T({error:C.InvalidRefreshTokenError});let s=await t.GenerateTokenPairs({id:o.id,role:o.role});return await e.dbContractor.removeAndAddRefreshToken({id:o.id,refreshToken:n.refreshToken,newRefreshToken:s.refreshToken}),delete o.refreshTokens,delete o.passwordHash,w({account:o,tokens:s})}function F({config:e,tokens:t}){return async(n,r)=>{try{let a=await P({config:e,tokens:t},{refreshToken:n.body.refreshToken});if(!a.success){let e=a.errors[0].error,t=400;return(e.code===i.InvalidRefreshToken||e.code===i.AccountNotFound)&&(t=401),e.code===i.ServerError&&(t=500),r.status(t).send({code:e.code,message:e.message})}return r.status(200).send({tokens:a.value.tokens})}catch(e){return console.error(`Refresh token error:`,e),r.status(500).send({code:i.ServerError})}}}async function I({config:e,tokens:t},{...r}){let i=_.safeParse(r);if(!i.success)return T({error:C.InvalidDataError(x(i))});if(!e.roles?.includes(r.role))return T({error:C.InvalidRoleError(e.roles)});if(await e.dbContractor.findAccountWithCredential({email:r.email,phoneNumber:r.phoneNumber}))return T({error:C.DuplicateAccountError});let a=await n.hash({pass:String(r.password),salt:`salt123`,type:n.ArgonType.Argon2d}),o=await e.dbContractor.createAccount({data:{email:r.email,phoneNumber:r.phoneNumber,passwordHash:a,role:r.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,config:e}),w({account:o,tokens:s})}function L({config:e,tokens:t}){return async(n,r)=>{try{let a=await I({config:e,tokens:t},n.body);if(!a.success){let e=a.errors[0].error,t=400;return e.code===i.InvalidRole||e.code===i.DuplicateAccount?t=409:e.code===i.ServerError&&(t=500),r.status(t).send({code:e.code,message:e.message})}return r.status(201).send(a.value)}catch(e){return console.error(`Register error:`,e),r.status(500).send({code:i.ServerError})}}}var R=class{Register=({config:e,tokens:t})=>L({config:e,tokens:t});Login=({config:e,tokens:t})=>k({config:e,tokens:t});Logout=({config:e,tokens:t})=>j({config:e,tokens:t});Refresh=({config:e,tokens:t})=>F({config:e,tokens:t});ChangePassword=({config:e,tokens:t,userId:n})=>D({config:e,tokens:t,userId:n});Guard=({config:e,tokens:t,roles:n})=>o({tokens:t,config:e,roles:n})};export{R as ExpressContractor};
1
+ import{createRequire as e}from"node:module";import{z as t}from"zod";import{parsePhoneNumberFromString as n}from"libphonenumber-js";import r from"node:crypto";var i=Object.create,a=Object.defineProperty,o=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,c=Object.getPrototypeOf,l=Object.prototype.hasOwnProperty,u=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports),d=(e,t,n,r)=>{if(t&&typeof t==`object`||typeof t==`function`)for(var i=s(t),c=0,u=i.length,d;c<u;c++)d=i[c],!l.call(e,d)&&d!==n&&a(e,d,{get:(e=>t[e]).bind(null,d),enumerable:!(r=o(t,d))||r.enumerable});return e},f=(e,t,n)=>(n=e==null?{}:i(c(e)),d(t||!e||!e.__esModule?a(n,`default`,{value:e,enumerable:!0}):n,e)),p=e(import.meta.url),m=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`;static SchemaValidationError=`schema-validation`;static SchemaValidationMessage=`Your database error is not is sync with CAuth Spec`};async function h(e){try{return{data:await e,error:null}}catch(e){return{data:null,error:e}}}function g({tokens:e,config:t,roles:n}){return async(r,i,a)=>{try{let o=r.cookies?.accessToken;if(!o){let e=r.headers.authorization;e?.startsWith(`Bearer `)&&(o=e.split(` `)[1])}if(!o)return i.status(401).send({code:m.InvalidToken});let s=await h(e.VerifyAccessToken(o));return s.error||!s.data?i.status(401).send({code:m.InvalidToken}):n&&!n.includes(s.data.role)||!t.roles.includes(s.data.role)?i.status(403).send({code:m.ForbiddenResource,message:m.ForbiddenResourceMessage}):(r.cauth={id:s.data.id,role:s.data.role},a())}catch{return i.status(500).send({code:m.ServerError})}}}const _=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),v=t.enum([`LOGIN`,`RESET_PASSWORD`,`ACTION`]),y=t.object({email:t.email(),phoneNumber:t.never().optional(),password:t.string().min(6).optional()}),b=t.object({phoneNumber:_,email:t.never().optional(),password:t.string().min(6).optional()}),x=t.union([y,b]).superRefine((e,n)=>{e.email&&e.phoneNumber&&n.addIssue({code:t.ZodIssueCode.custom,message:`Provide either email or phoneNumber`,path:[`email`,`phoneNumber`]})}),S=t.object({phoneNumber:_,email:t.never().optional(),code:t.string().min(4).max(8)}),C=t.object({email:t.email(),phoneNumber:t.never().optional(),code:t.string().min(4).max(8)});t.union([C,S]);const w=t.object({otpPurpose:v,usePassword:t.boolean().default(!1),password:t.string().optional()}),T=w.extend({phoneNumber:_,email:t.never().optional()}),E=w.extend({phoneNumber:t.never().optional(),email:t.string().email()});t.union([T,E]).refine(e=>e.usePassword?!!e.password:!e.password,{message:`Password required only if usePassword is true`,path:[`password`]});const D=t.object({phoneNumber:_.optional(),email:t.email().optional(),role:t.string(),password:t.string().optional()}).superRefine((e,n)=>{!e.email&&!e.phoneNumber&&n.addIssue({code:t.ZodIssueCode.custom,message:`Provide either email or phoneNumber`,path:[`email`,`phoneNumber`]})}),O=t.object({refreshToken:t.string()}),k=t.object({refreshToken:t.string()}),A=t.object({accountId:t.string(),oldPassword:t.string(),newPassword:t.string()});function j(e){return`${e?.error?.issues[0].path}: ${e?.error?.issues[0].message}`}var M=class{static ValidationError=`validation-error`;static CredentialError=`credential-error`;static UnKnownError=`unknown-error`;static InvalidDataError=`invalid-data-error`};const N={CredentialMismatchError:{type:M.CredentialError,message:m.CredentialMismatchMessage,code:m.CredentialMismatch,name:`CredentialMismatchError`},InvalidDataError:e=>({type:M.ValidationError,message:m.InvalidDataMessage(e),code:m.InvalidData,name:`InvalidDataError`}),AccountNotFoundError:{type:M.InvalidDataError,message:m.AccountNotFoundMessage,code:m.AccountNotFound,name:`AccountNotFoundError`},InvalidRoleError:e=>({type:M.ValidationError,message:m.InvalidRoleMessage(e),code:m.InvalidRole,name:`InvalidRoleError`}),InvalidRefreshTokenError:{type:M.ValidationError,message:m.InvalidRefreshTokenMessage,code:m.InvalidRefreshToken,name:`InvalidRefreshTokenError`},DuplicateAccountError:{type:M.ValidationError,message:m.DuplicateAccountMessage,code:m.DuplicateAccount,name:`DuplicateAccountError`},InvalidOTPCode:{type:M.ValidationError,message:m.InvalidOtpMessage,code:m.InvalidOtp,name:`InvalidOTPCode`},SchemaInvalidError:{type:M.ValidationError,message:m.SchemaValidationMessage,code:m.SchemaValidationError,name:`SchemaInvalidError`}};function P(e){return{success:!0,value:e}}function F(...e){return{success:!1,errors:e}}var I=u(((e,t)=>{var n=p(`fs`),r=p(`path`),i=p(`os`),a=typeof __webpack_require__==`function`?__non_webpack_require__:p,o=process.config&&process.config.variables||{},s=!!process.env.PREBUILDS_ONLY,c=process.versions.modules,l=O()?`electron`:D()?`node-webkit`:`node`,u=process.env.npm_config_arch||i.arch(),d=process.env.npm_config_platform||i.platform(),f=process.env.LIBC||(k(d)?`musl`:`glibc`),m=process.env.ARM_VERSION||(u===`arm64`?`8`:o.arm_version)||``,h=(process.versions.uv||``).split(`.`)[0];t.exports=g;function g(e){return a(g.resolve(e))}g.resolve=g.path=function(e){e=r.resolve(e||`.`);try{var t=a(r.join(e,`package.json`)).name.toUpperCase().replace(/-/g,`_`);process.env[t+`_PREBUILD`]&&(e=process.env[t+`_PREBUILD`])}catch{}if(!s){var n=v(r.join(e,`build/Release`),y);if(n)return n;var i=v(r.join(e,`build/Debug`),y);if(i)return i}var o=T(e);if(o)return o;var p=T(r.dirname(process.execPath));if(p)return p;var g=[`platform=`+d,`arch=`+u,`runtime=`+l,`abi=`+c,`uv=`+h,m?`armv=`+m:``,`libc=`+f,`node=`+process.versions.node,process.versions.electron?`electron=`+process.versions.electron:``,typeof __webpack_require__==`function`?`webpack=true`:``].filter(Boolean).join(` `);throw Error(`No native build was found for `+g+`
2
+ loaded from: `+e+`
3
+ `);function T(e){var t=_(r.join(e,`prebuilds`)).map(b).filter(x(d,u)).sort(S)[0];if(t){var n=r.join(e,`prebuilds`,t.name),i=_(n).map(C).filter(w(l,c)).sort(E(l))[0];if(i)return r.join(n,i.file)}}};function _(e){try{return n.readdirSync(e)}catch{return[]}}function v(e,t){var n=_(e).filter(t);return n[0]&&r.join(e,n[0])}function y(e){return/\.node$/.test(e)}function b(e){var t=e.split(`-`);if(t.length===2){var n=t[0],r=t[1].split(`+`);if(n&&r.length&&r.every(Boolean))return{name:e,platform:n,architectures:r}}}function x(e,t){return function(n){return n==null||n.platform!==e?!1:n.architectures.includes(t)}}function S(e,t){return e.architectures.length-t.architectures.length}function C(e){var t=e.split(`.`),n=t.pop(),r={file:e,specificity:0};if(n===`node`){for(var i=0;i<t.length;i++){var a=t[i];if(a===`node`||a===`electron`||a===`node-webkit`)r.runtime=a;else if(a===`napi`)r.napi=!0;else if(a.slice(0,3)===`abi`)r.abi=a.slice(3);else if(a.slice(0,2)===`uv`)r.uv=a.slice(2);else if(a.slice(0,4)===`armv`)r.armv=a.slice(4);else if(a===`glibc`||a===`musl`)r.libc=a;else continue;r.specificity++}return r}}function w(e,t){return function(n){return!(n==null||n.runtime&&n.runtime!==e&&!T(n)||n.abi&&n.abi!==t&&!n.napi||n.uv&&n.uv!==h||n.armv&&n.armv!==m||n.libc&&n.libc!==f)}}function T(e){return e.runtime===`node`&&e.napi}function E(e){return function(t,n){return t.runtime===n.runtime?t.abi===n.abi?t.specificity===n.specificity?0:t.specificity>n.specificity?-1:1:t.abi?-1:1:t.runtime===e?-1:1}}function D(){return!!(process.versions&&process.versions.nw)}function O(){return process.versions&&process.versions.electron||process.env.ELECTRON_RUN_AS_NODE?!0:typeof window<`u`&&window.process&&window.process.type===`renderer`}function k(e){return e===`linux`&&n.existsSync(`/etc/alpine-release`)}g.parseTags=C,g.matchTags=w,g.compareTags=E,g.parseTuple=b,g.matchTuple=x,g.compareTuples=S})),L=u(((e,t)=>{let n=typeof __webpack_require__==`function`?__non_webpack_require__:p;typeof n.addon==`function`?t.exports=n.addon.bind(n):t.exports=I()})),R=u(((e,t)=>{let n=global.Promise;function r(e,t,r){return Array.isArray(r)||(r=Array.prototype.slice.call(r)),typeof e==`function`?new n((n,i)=>{r.push((e,t)=>{e?i(e):n(t)}),e.apply(t,r)}):n.reject(Error(`fn must be a function`))}function i(e){return n.reject(e)}function a(e){n=e}t.exports={promise:r,reject:i,use:a}})),z=u(((e,t)=>{let n=p(`path`),r=L()(n.resolve(__dirname)),i=p(`crypto`),a=R();function o(e,t){if(!e)e=10;else if(typeof e!=`number`)throw Error(`rounds must be a number`);if(!t)t=`b`;else if(t!==`b`&&t!==`a`)throw Error(`minor must be either "a" or "b"`);return r.gen_salt_sync(t,e,i.randomBytes(16))}function s(e,t,n){let o;if(typeof arguments[0]==`function`?(n=arguments[0],e=10,t=`b`):typeof arguments[1]==`function`&&(n=arguments[1],t=`b`),!n)return a.promise(s,this,[e,t]);if(!e)e=10;else if(typeof e!=`number`)return o=Error(`rounds must be a number`),process.nextTick(function(){n(o)});if(!t)t=`b`;else if(t!==`b`&&t!==`a`)return o=Error(`minor must be either "a" or "b"`),process.nextTick(function(){n(o)});i.randomBytes(16,function(i,a){if(i){n(i);return}r.gen_salt(t,e,a,n)})}function c(e,n){if(e==null||n==null)throw Error(`data and salt arguments required`);if(!(typeof e==`string`||e instanceof Buffer)||typeof n!=`string`&&typeof n!=`number`)throw Error(`data must be a string or Buffer and salt must either be a salt string or a number of rounds`);return typeof n==`number`&&(n=t.exports.genSaltSync(n)),r.encrypt_sync(e,n)}function l(e,n,i){let o;return typeof e==`function`?(o=Error(`data must be a string or Buffer and salt must either be a salt string or a number of rounds`),process.nextTick(function(){e(o)})):typeof n==`function`?(o=Error(`data must be a string or Buffer and salt must either be a salt string or a number of rounds`),process.nextTick(function(){n(o)})):i&&typeof i!=`function`?a.reject(Error(`cb must be a function or null to return a Promise`)):i?e==null||n==null?(o=Error(`data and salt arguments required`),process.nextTick(function(){i(o)})):!(typeof e==`string`||e instanceof Buffer)||typeof n!=`string`&&typeof n!=`number`?(o=Error(`data must be a string or Buffer and salt must either be a salt string or a number of rounds`),process.nextTick(function(){i(o)})):typeof n==`number`?t.exports.genSalt(n,function(t,n){return r.encrypt(e,n,i)}):r.encrypt(e,n,i):a.promise(l,this,[e,n])}function u(e,t){if(e==null||t==null)throw Error(`data and hash arguments required`);if(!(typeof e==`string`||e instanceof Buffer)||typeof t!=`string`)throw Error(`data must be a string or Buffer and hash must be a string`);return r.compare_sync(e,t)}function d(e,t,n){let i;return typeof e==`function`?(i=Error(`data and hash arguments required`),process.nextTick(function(){e(i)})):typeof t==`function`?(i=Error(`data and hash arguments required`),process.nextTick(function(){t(i)})):n&&typeof n!=`function`?a.reject(Error(`cb must be a function or null to return a Promise`)):n?e==null||t==null?(i=Error(`data and hash arguments required`),process.nextTick(function(){n(i)})):!(typeof e==`string`||e instanceof Buffer)||typeof t!=`string`?(i=Error(`data and hash must be strings`),process.nextTick(function(){n(i)})):r.compare(e,t,n):a.promise(d,this,[e,t])}function f(e){if(e==null)throw Error(`hash argument required`);if(typeof e!=`string`)throw Error(`hash must be a string`);return r.get_rounds(e)}t.exports={genSaltSync:o,genSalt:s,hashSync:c,hash:l,compareSync:u,compare:d,getRounds:f}})),B=f(z(),1);async function V({config:e},{...t}){let n=A.safeParse(t);if(!n.success)return F({error:N.InvalidDataError(j(n))});let r=await e.dbContractor.findAccountById({id:t.accountId});if(!r||!await B.default.compare(String(t.oldPassword),String(r.passwordHash)))return F({error:N.CredentialMismatchError});let i=await B.default.hash(t.newPassword,10);return await e.dbContractor.updateAccount({id:r.id,data:{passwordHash:i}}),P({})}function H({config:e,userId:t}){return async(n,r)=>{try{let i=await V({config:e},{accountId:t,oldPassword:n.body.oldPassword,newPassword:n.body.newPassword});if(!i.success){let e=i.errors[0].error,t=400;return e.code===m.InvalidRole||e.code===m.DuplicateAccount?t=409:e.code===m.ServerError&&(t=500),r.status(t).send({code:e.code,message:e.message})}return r.status(200).send({code:`password-changed`})}catch(e){return console.error(`ChangePassword error:`,e),r.status(500).send({code:m.ServerError})}}}var U=f(z(),1);async function W({config:e,tokens:t},{...n}){let r=x.safeParse(n);if(!r.success)return F({error:N.InvalidDataError(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 F({error:N.CredentialMismatchError});let a=await t.GenerateTokenPairs({id:i.id,role:i.role});return await e.dbContractor.updateAccountLogin({id:i.id,refreshToken:a.refreshToken,config:e}),delete i.passwordHash,delete i.refreshTokens,P({account:i,tokens:a})}function G({config:e,tokens:t}){return async(n,r)=>{try{let i=await W({config:e,tokens:t},n.body);if(!i.success){let e=i.errors[0].error,t=400;return e.code===m.CredentialMismatch?t=409:e.code===m.ServerError&&(t=500),r.status(t).send({code:e.code,message:e.message})}return r.status(200).send(i.value)}catch{return r.status(500).send({code:m.ServerError})}}}async function K({config:e,tokens:t},{...n}){let r=k.safeParse(n);if(!r.success)return F({error:N.InvalidDataError(j(r))});let i=await h(t.VerifyRefreshToken(n.refreshToken));return i.error||!i?F({error:N.InvalidRefreshTokenError}):(await e.dbContractor.removeAndAddRefreshToken({id:String(i.data?.id),refreshToken:n.refreshToken}),P({}))}function q({config:e,tokens:t}){return async(n,r)=>{try{let i=await K({config:e,tokens:t},{refreshToken:n.body.refreshToken});if(!i.success){let e=i.errors[0].error,t=400;return e.code===m.InvalidRole||e.code===m.DuplicateAccount?t=409:e.code===m.ServerError&&(t=500),r.status(t).send({code:e.code,message:e.message})}return r.status(200).send({code:`logged-out`})}catch(e){return console.error(`Logout error:`,e),r.status(500).send({code:`server-error`})}}}function J({token:e,refreshTokenSecret:t}){return r.createHmac(`sha256`,t).update(e).digest(`hex`)}function Y({incomingToken:e,storedHash:t,refreshTokenSecret:n}){let i=J({token:e,refreshTokenSecret:n});return r.timingSafeEqual(Buffer.from(i),Buffer.from(t))}async function X({config:e,tokens:t},{...n}){let r=O.safeParse(n);if(!r.success)return F({error:N.InvalidDataError(j(r))});let i=await h(t.VerifyRefreshToken(n.refreshToken));if(i.error)return F({error:N.InvalidRefreshTokenError});let a=await e.dbContractor.findAccountById({id:String(i.data?.id)});if(!a)return F({error:N.AccountNotFoundError});if(!a?.refreshTokens?.some(t=>Y({incomingToken:n.refreshToken,storedHash:t.token,refreshTokenSecret:e.jwtConfig.refreshTokenSecret})))return F({error:N.InvalidRefreshTokenError});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,P({account:a,tokens:o})}function Z({config:e,tokens:t}){return async(n,r)=>{try{let i=await X({config:e,tokens:t},{refreshToken:n.body.refreshToken});if(!i.success){let e=i.errors[0].error,t=400;return(e.code===m.InvalidRefreshToken||e.code===m.AccountNotFound)&&(t=401),e.code===m.ServerError&&(t=500),r.status(t).send({code:e.code,message:e.message})}return r.status(200).send({tokens:i.value.tokens})}catch(e){return console.error(`Refresh token error:`,e),r.status(500).send({code:m.ServerError})}}}var Q=f(z(),1);async function $({config:e,tokens:t},{...n}){let r=D.safeParse(n);if(!r.success)return F({error:N.InvalidDataError(j(r))});if(!e.roles?.includes(n.role))return F({error:N.InvalidRoleError(e.roles)});if(await e.dbContractor.findAccountWithCredential({email:n.email,phoneNumber:n.phoneNumber}))return F({error:N.DuplicateAccountError});let i=await Q.default.hash(String(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,config:e}),P({account:a,tokens:o})}function ee({config:e,tokens:t}){return async(n,r)=>{try{let i=await $({config:e,tokens:t},n.body);if(!i.success){let e=i.errors[0].error,t=400;return e.code===m.InvalidRole||e.code===m.DuplicateAccount?t=409:e.code===m.ServerError&&(t=500),r.status(t).send({code:e.code,message:e.message})}return r.status(201).send(i.value)}catch(e){return console.error(`Register error:`,e),r.status(500).send({code:m.ServerError})}}}var te=class{Register=({config:e,tokens:t})=>ee({config:e,tokens:t});Login=({config:e,tokens:t})=>G({config:e,tokens:t});Logout=({config:e,tokens:t})=>q({config:e,tokens:t});Refresh=({config:e,tokens:t})=>Z({config:e,tokens:t});ChangePassword=({config:e,tokens:t,userId:n})=>H({config:e,tokens:t,userId:n});Guard=({config:e,tokens:t,roles:n})=>g({tokens:t,config:e,roles:n})};export{te as ExpressContractor};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cauth/express",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -26,9 +26,6 @@
26
26
  "author": "Jonace Mpelule <jonacempelule123@gmail.com> (https://github.com/jonace-mpelule)",
27
27
  "license": "MIT",
28
28
  "packageManager": "pnpm@10.13.1",
29
- "peerDependencies": {
30
- "argon2": "^0.44.0"
31
- },
32
29
  "devDependencies": {
33
30
  "@types/express": "^5.0.3",
34
31
  "@types/node": "^24.7.0",
@@ -36,7 +33,6 @@
36
33
  "typescript": "^5.9.3"
37
34
  },
38
35
  "dependencies": {
39
- "argon2-browser": "^1.18.0",
40
36
  "express": "^5.1.0",
41
37
  "jsonwebtoken": "^9.0.2",
42
38
  "libphonenumber-js": "^1.12.23",