pico-auth 0.0.36 → 0.0.39
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/pico-auth.d.ts
CHANGED
|
@@ -48,7 +48,7 @@ declare module "core/auth" {
|
|
|
48
48
|
export const authenticateWithScratchCard: (cardCode: string, userProvider: UserProvider, scratchCardProvider: ScratchCardProvider, jwtSpecs: JWTSpecs, requesterLogin?: string) => Promise<{
|
|
49
49
|
token: any;
|
|
50
50
|
refreshToken: any;
|
|
51
|
-
user:
|
|
51
|
+
user: BaseUser;
|
|
52
52
|
}>;
|
|
53
53
|
/**
|
|
54
54
|
* When new short lived token is requested
|
package/dist/pico-auth.esm.js
CHANGED
|
@@ -132,15 +132,15 @@ const authenticateWithScratchCard = async (cardCode, userProvider, scratchCardPr
|
|
|
132
132
|
throw new Error(`Failed card authentication attempt ${requesterLogin} (Blocked as Target)`);
|
|
133
133
|
// ok so we will use targetUser as a user that will be actually logged in
|
|
134
134
|
// in impersonation scenario targetUser may be different then the user.
|
|
135
|
-
const
|
|
135
|
+
const jwtData = await issueJwtToken(targetUser, userProvider, jwtSpecs, false);
|
|
136
136
|
let refreshToken;
|
|
137
137
|
if (jwtSpecs.refreshExpiryTimeMs)
|
|
138
138
|
refreshToken = (await issueJwtToken(targetUser, userProvider, jwtSpecs, true)).token;
|
|
139
139
|
console.info(`Card authentication success. Requester:${requesterLogin} Target:${targetUser.id}`);
|
|
140
140
|
return {
|
|
141
|
-
token,
|
|
141
|
+
token: jwtData.token,
|
|
142
142
|
refreshToken,
|
|
143
|
-
user:
|
|
143
|
+
user: jwtData.clearedUser // just in case its impersonation so the actual resulting user will be different that the requester login user
|
|
144
144
|
};
|
|
145
145
|
}
|
|
146
146
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const speakeasy=require("speakeasy"),qrcode=require("qrcode"),md5=require("md5"),jwt=require("jsonwebtoken"),issueJwtToken=async(e,t,r,a)=>{let i=r.secretKey,o=t.getSafeUser?await t.getSafeUser(e):e;o=t.getUserPostAuthenticate?await t.getUserPostAuthenticate(o):o;let s,n={time:Date.now(),user:o};return a&&r.refreshExpiryTimeMs?s=jwt.sign(n,i,{expiresIn:r.refreshExpiryTimeMs}):r.expiryTimeMs&&(s=jwt.sign(n,i,{expiresIn:r.expiryTimeMs})),{token:s,clearedUser:o}},authenticate=async(e,t,r,a,i,o,s)=>{var n;let c=await i.getUser(e);const l=i.userSecretPath?c[i.userSecretPath]:c.mfa,d=i.userPasswordPath?c[i.userPasswordPath]:c.password;if(null==l?void 0:l.enabled){if(!speakeasy.totp.verify({secret:null===(n=null==l?void 0:l.secret)||void 0===n?void 0:n.actual,encoding:"base32",token:r,window:1}))throw new Error(`Failed authentication attempt ${e} (MFA Enabled)`)}if(c.blocked)throw new Error(`Failed authentication attempt ${e} (Blocked)`);if(md5(t||"")==d){const e=a,t=c;if(e){let r=!1;if(e.startsWith("@")){if(r=r||await o.canImpersonate(c,e),!r)throw new Error(`Failed impersonate attempt. From: ${t.id} into ${e}`);await o.impersonateOrg(c,e)}else{const a=await i.getUser(e);if(r=r||await o.canImpersonate(c,e),!r)throw new Error(`Failed impersonate attempt. From: ${t.id} into ${e}`);c=a}console.info(`Impersonate success. From: ${t.login} into ${e}`)}const r=(await issueJwtToken(c,i,s,!1)).token;let n;return s.refreshExpiryTimeMs&&(n=(await issueJwtToken(c,i,s,!0)).token),console.log(`Successful login: ${c.id}`),{token:r,refreshToken:n}}throw new Error(`Failed authentication attempt ${e}`)},authenticateWithScratchCard=async(e,t,r,a,i)=>{let o,s=i?await t.getUser(i):void 0;if(s&&s.blocked)throw new Error(`Failed card authentication attempt ${i} (Blocked)`);if(i&&!s)throw new Error(`Failed card authentication attempt ${i} (Missing user)`);try{o=await r.consume(e,s)}catch(e){throw new Error(`Failed card authentication attempt ${i} (Consume Failed)`)}try{if(!o)throw new Error(`Failed card authentication attempt ${i} (Consume Failed)`);if(o.blocked)throw new Error(`Failed card authentication attempt ${i} (Blocked as Target)`);const e=
|
|
1
|
+
const speakeasy=require("speakeasy"),qrcode=require("qrcode"),md5=require("md5"),jwt=require("jsonwebtoken"),issueJwtToken=async(e,t,r,a)=>{let i=r.secretKey,o=t.getSafeUser?await t.getSafeUser(e):e;o=t.getUserPostAuthenticate?await t.getUserPostAuthenticate(o):o;let s,n={time:Date.now(),user:o};return a&&r.refreshExpiryTimeMs?s=jwt.sign(n,i,{expiresIn:r.refreshExpiryTimeMs}):r.expiryTimeMs&&(s=jwt.sign(n,i,{expiresIn:r.expiryTimeMs})),{token:s,clearedUser:o}},authenticate=async(e,t,r,a,i,o,s)=>{var n;let c=await i.getUser(e);const l=i.userSecretPath?c[i.userSecretPath]:c.mfa,d=i.userPasswordPath?c[i.userPasswordPath]:c.password;if(null==l?void 0:l.enabled){if(!speakeasy.totp.verify({secret:null===(n=null==l?void 0:l.secret)||void 0===n?void 0:n.actual,encoding:"base32",token:r,window:1}))throw new Error(`Failed authentication attempt ${e} (MFA Enabled)`)}if(c.blocked)throw new Error(`Failed authentication attempt ${e} (Blocked)`);if(md5(t||"")==d){const e=a,t=c;if(e){let r=!1;if(e.startsWith("@")){if(r=r||await o.canImpersonate(c,e),!r)throw new Error(`Failed impersonate attempt. From: ${t.id} into ${e}`);await o.impersonateOrg(c,e)}else{const a=await i.getUser(e);if(r=r||await o.canImpersonate(c,e),!r)throw new Error(`Failed impersonate attempt. From: ${t.id} into ${e}`);c=a}console.info(`Impersonate success. From: ${t.login} into ${e}`)}const r=(await issueJwtToken(c,i,s,!1)).token;let n;return s.refreshExpiryTimeMs&&(n=(await issueJwtToken(c,i,s,!0)).token),console.log(`Successful login: ${c.id}`),{token:r,refreshToken:n}}throw new Error(`Failed authentication attempt ${e}`)},authenticateWithScratchCard=async(e,t,r,a,i)=>{let o,s=i?await t.getUser(i):void 0;if(s&&s.blocked)throw new Error(`Failed card authentication attempt ${i} (Blocked)`);if(i&&!s)throw new Error(`Failed card authentication attempt ${i} (Missing user)`);try{o=await r.consume(e,s)}catch(e){throw new Error(`Failed card authentication attempt ${i} (Consume Failed)`)}try{if(!o)throw new Error(`Failed card authentication attempt ${i} (Consume Failed)`);if(o.blocked)throw new Error(`Failed card authentication attempt ${i} (Blocked as Target)`);const e=await issueJwtToken(o,t,a,!1);let r;return a.refreshExpiryTimeMs&&(r=(await issueJwtToken(o,t,a,!0)).token),console.info(`Card authentication success. Requester:${i} Target:${o.id}`),{token:e.token,refreshToken:r,user:e.clearedUser}}catch(e){throw new Error(`Failed card authentication attempt ${i}`)}},refreshToken=async(e,t,r,a)=>{let i=await r.getUser(e);if(i.blocked)throw new Error(`Failed refresh token attempt ${e} (Blocked)`);if(t){let o=a.secretKey;const s=jwt.verify(t,o).user;if(!s||s.id!=i.id)throw new Error(`Failed refresh token attempt ${e} (Invalid Token)`);const n=(await issueJwtToken(i,r,a,!1)).token;let c;return a.refreshExpiryTimeMs&&(c=(await issueJwtToken(i,r,a,!0)).token),console.log(`Successful token refresh: ${i.id}`),{token:n,refreshToken:c}}throw new Error(`Failed refresh token attempt ${e}`)},mfaRegister=async(e,t,r)=>new Promise(async(a,i)=>{let o=await r.getUser(t),s=r.userSecretPath?o[r.userSecretPath]:o.mfa;const n=speakeasy.generateSecret({name:`${e}: ${t}`});if(!s){s={secret:{temp:void 0,actual:void 0},enabled:!1};o[r.userSecretPath?r.userSecretPath:"mfa"]=s}s.secret.temp=n.base32,s.secret.actual=void 0,await r.putUser(o),qrcode.toDataURL(n.otpauth_url,(e,t)=>{if(e)throw new Error("Error generating QR code");a({qr_code:t,secret:n.base32})})}),mfaVerify=async(e,t,r)=>{var a,i;const o=t;let s=await r.getUser(e);const n=r.userSecretPath?s[r.userSecretPath]:s.mfa;return speakeasy.totp.verify({secret:null===(a=null==n?void 0:n.secret)||void 0===a?void 0:a.temp,encoding:"base32",token:o})?(n.secret.actual=null===(i=null==n?void 0:n.secret)||void 0===i?void 0:i.temp,n.enabled=!0,await r.putUser(s),!0):(console.log(`Failed mfa verification for ${e}`),!1)},mfaEnabled=async(e,t)=>{let r=await t.getUser(e);const a=t.userSecretPath?r[t.userSecretPath]:r.mfa;return(null==a?void 0:a.enabled)||!1};export{authenticate,authenticateWithScratchCard,issueJwtToken,mfaEnabled,mfaRegister,mfaVerify,refreshToken};
|
package/dist/pico-auth.umd.js
CHANGED
|
@@ -138,15 +138,15 @@
|
|
|
138
138
|
throw new Error(`Failed card authentication attempt ${requesterLogin} (Blocked as Target)`);
|
|
139
139
|
// ok so we will use targetUser as a user that will be actually logged in
|
|
140
140
|
// in impersonation scenario targetUser may be different then the user.
|
|
141
|
-
const
|
|
141
|
+
const jwtData = await issueJwtToken(targetUser, userProvider, jwtSpecs, false);
|
|
142
142
|
let refreshToken;
|
|
143
143
|
if (jwtSpecs.refreshExpiryTimeMs)
|
|
144
144
|
refreshToken = (await issueJwtToken(targetUser, userProvider, jwtSpecs, true)).token;
|
|
145
145
|
console.info(`Card authentication success. Requester:${requesterLogin} Target:${targetUser.id}`);
|
|
146
146
|
return {
|
|
147
|
-
token,
|
|
147
|
+
token: jwtData.token,
|
|
148
148
|
refreshToken,
|
|
149
|
-
user:
|
|
149
|
+
user: jwtData.clearedUser // just in case its impersonation so the actual resulting user will be different that the requester login user
|
|
150
150
|
};
|
|
151
151
|
}
|
|
152
152
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).picoAuth={})}(this,function(e){"use strict";const t=require("speakeasy"),r=require("qrcode"),a=require("md5"),o=require("jsonwebtoken"),i=async(e,t,r,a)=>{let i=r.secretKey,n=t.getSafeUser?await t.getSafeUser(e):e;n=t.getUserPostAuthenticate?await t.getUserPostAuthenticate(n):n;let s,c={time:Date.now(),user:n};return a&&r.refreshExpiryTimeMs?s=o.sign(c,i,{expiresIn:r.refreshExpiryTimeMs}):r.expiryTimeMs&&(s=o.sign(c,i,{expiresIn:r.expiryTimeMs})),{token:s,clearedUser:n}};e.authenticate=async(e,r,o,n,s,c,l)=>{var d;let u=await s.getUser(e);const f=s.userSecretPath?u[s.userSecretPath]:u.mfa,h=s.userPasswordPath?u[s.userPasswordPath]:u.password;if(null==f?void 0:f.enabled){if(!t.totp.verify({secret:null===(d=null==f?void 0:f.secret)||void 0===d?void 0:d.actual,encoding:"base32",token:o,window:1}))throw new Error(`Failed authentication attempt ${e} (MFA Enabled)`)}if(u.blocked)throw new Error(`Failed authentication attempt ${e} (Blocked)`);if(a(r||"")==h){const e=n,t=u;if(e){let r=!1;if(e.startsWith("@")){if(r=r||await c.canImpersonate(u,e),!r)throw new Error(`Failed impersonate attempt. From: ${t.id} into ${e}`);await c.impersonateOrg(u,e)}else{const a=await s.getUser(e);if(r=r||await c.canImpersonate(u,e),!r)throw new Error(`Failed impersonate attempt. From: ${t.id} into ${e}`);u=a}console.info(`Impersonate success. From: ${t.login} into ${e}`)}const r=(await i(u,s,l,!1)).token;let a;return l.refreshExpiryTimeMs&&(a=(await i(u,s,l,!0)).token),console.log(`Successful login: ${u.id}`),{token:r,refreshToken:a}}throw new Error(`Failed authentication attempt ${e}`)},e.authenticateWithScratchCard=async(e,t,r,a,o)=>{let n,s=o?await t.getUser(o):void 0;if(s&&s.blocked)throw new Error(`Failed card authentication attempt ${o} (Blocked)`);if(o&&!s)throw new Error(`Failed card authentication attempt ${o} (Missing user)`);try{n=await r.consume(e,s)}catch(e){throw new Error(`Failed card authentication attempt ${o} (Consume Failed)`)}try{if(!n)throw new Error(`Failed card authentication attempt ${o} (Consume Failed)`);if(n.blocked)throw new Error(`Failed card authentication attempt ${o} (Blocked as Target)`);const e=
|
|
1
|
+
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).picoAuth={})}(this,function(e){"use strict";const t=require("speakeasy"),r=require("qrcode"),a=require("md5"),o=require("jsonwebtoken"),i=async(e,t,r,a)=>{let i=r.secretKey,n=t.getSafeUser?await t.getSafeUser(e):e;n=t.getUserPostAuthenticate?await t.getUserPostAuthenticate(n):n;let s,c={time:Date.now(),user:n};return a&&r.refreshExpiryTimeMs?s=o.sign(c,i,{expiresIn:r.refreshExpiryTimeMs}):r.expiryTimeMs&&(s=o.sign(c,i,{expiresIn:r.expiryTimeMs})),{token:s,clearedUser:n}};e.authenticate=async(e,r,o,n,s,c,l)=>{var d;let u=await s.getUser(e);const f=s.userSecretPath?u[s.userSecretPath]:u.mfa,h=s.userPasswordPath?u[s.userPasswordPath]:u.password;if(null==f?void 0:f.enabled){if(!t.totp.verify({secret:null===(d=null==f?void 0:f.secret)||void 0===d?void 0:d.actual,encoding:"base32",token:o,window:1}))throw new Error(`Failed authentication attempt ${e} (MFA Enabled)`)}if(u.blocked)throw new Error(`Failed authentication attempt ${e} (Blocked)`);if(a(r||"")==h){const e=n,t=u;if(e){let r=!1;if(e.startsWith("@")){if(r=r||await c.canImpersonate(u,e),!r)throw new Error(`Failed impersonate attempt. From: ${t.id} into ${e}`);await c.impersonateOrg(u,e)}else{const a=await s.getUser(e);if(r=r||await c.canImpersonate(u,e),!r)throw new Error(`Failed impersonate attempt. From: ${t.id} into ${e}`);u=a}console.info(`Impersonate success. From: ${t.login} into ${e}`)}const r=(await i(u,s,l,!1)).token;let a;return l.refreshExpiryTimeMs&&(a=(await i(u,s,l,!0)).token),console.log(`Successful login: ${u.id}`),{token:r,refreshToken:a}}throw new Error(`Failed authentication attempt ${e}`)},e.authenticateWithScratchCard=async(e,t,r,a,o)=>{let n,s=o?await t.getUser(o):void 0;if(s&&s.blocked)throw new Error(`Failed card authentication attempt ${o} (Blocked)`);if(o&&!s)throw new Error(`Failed card authentication attempt ${o} (Missing user)`);try{n=await r.consume(e,s)}catch(e){throw new Error(`Failed card authentication attempt ${o} (Consume Failed)`)}try{if(!n)throw new Error(`Failed card authentication attempt ${o} (Consume Failed)`);if(n.blocked)throw new Error(`Failed card authentication attempt ${o} (Blocked as Target)`);const e=await i(n,t,a,!1);let r;return a.refreshExpiryTimeMs&&(r=(await i(n,t,a,!0)).token),console.info(`Card authentication success. Requester:${o} Target:${n.id}`),{token:e.token,refreshToken:r,user:e.clearedUser}}catch(e){throw new Error(`Failed card authentication attempt ${o}`)}},e.issueJwtToken=i,e.mfaEnabled=async(e,t)=>{let r=await t.getUser(e);const a=t.userSecretPath?r[t.userSecretPath]:r.mfa;return(null==a?void 0:a.enabled)||!1},e.mfaRegister=async(e,a,o)=>new Promise(async(i,n)=>{let s=await o.getUser(a),c=o.userSecretPath?s[o.userSecretPath]:s.mfa;const l=t.generateSecret({name:`${e}: ${a}`});if(!c){c={secret:{temp:void 0,actual:void 0},enabled:!1};s[o.userSecretPath?o.userSecretPath:"mfa"]=c}c.secret.temp=l.base32,c.secret.actual=void 0,await o.putUser(s),r.toDataURL(l.otpauth_url,(e,t)=>{if(e)throw new Error("Error generating QR code");i({qr_code:t,secret:l.base32})})}),e.mfaVerify=async(e,r,a)=>{var o,i;const n=r;let s=await a.getUser(e);const c=a.userSecretPath?s[a.userSecretPath]:s.mfa;return t.totp.verify({secret:null===(o=null==c?void 0:c.secret)||void 0===o?void 0:o.temp,encoding:"base32",token:n})?(c.secret.actual=null===(i=null==c?void 0:c.secret)||void 0===i?void 0:i.temp,c.enabled=!0,await a.putUser(s),!0):(console.log(`Failed mfa verification for ${e}`),!1)},e.refreshToken=async(e,t,r,a)=>{let n=await r.getUser(e);if(n.blocked)throw new Error(`Failed refresh token attempt ${e} (Blocked)`);if(t){let s=a.secretKey;const c=o.verify(t,s).user;if(!c||c.id!=n.id)throw new Error(`Failed refresh token attempt ${e} (Invalid Token)`);const l=(await i(n,r,a,!1)).token;let d;return a.refreshExpiryTimeMs&&(d=(await i(n,r,a,!0)).token),console.log(`Successful token refresh: ${n.id}`),{token:l,refreshToken:d}}throw new Error(`Failed refresh token attempt ${e}`)},Object.defineProperty(e,"__esModule",{value:!0})});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pico-auth",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.39",
|
|
4
4
|
"description": "Minimal auth with user/pass, impersonation and mfa authentication",
|
|
5
5
|
"main": "dist/pico-auth.umd.js",
|
|
6
6
|
"types": "dist/pico-auth.d.ts",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"build:minjs:umd": "terser dist/pico-auth.umd.js --compress --mangle > dist/pico-auth.umd.min.js",
|
|
36
36
|
"build:minjs:esm": "terser dist/pico-auth.esm.js --compress --mangle > dist/pico-auth.esm.min.js",
|
|
37
37
|
"build:types": "tsc -t esnext --moduleResolution node -d --emitDeclarationOnly --outFile dist/pico-auth.d.ts src/pico-auth.ts",
|
|
38
|
-
"test": "
|
|
38
|
+
"test": "jest --coverage",
|
|
39
|
+
"test:jest": "jest",
|
|
39
40
|
"coverage": "nyc --reporter html --reporter text npm test",
|
|
40
41
|
"release-minor": "npm install && npm update && npm run build && npm run coverage && npm version minor && git push origin && git push origin --tags && npm publish",
|
|
41
42
|
"release-patch": "npm install && npm update && npm run build && npm version patch && npm publish"
|
|
@@ -57,20 +58,20 @@
|
|
|
57
58
|
"@rollup/plugin-commonjs": "28.0.1",
|
|
58
59
|
"@types/chai": "4.2.14",
|
|
59
60
|
"@types/chai-as-promised": "7.1.3",
|
|
60
|
-
"@types/
|
|
61
|
+
"@types/jest": "^29.5.12",
|
|
61
62
|
"@types/node": "20.5.0",
|
|
62
|
-
"@types/sinon": "9.0.8",
|
|
63
63
|
"@typescript-eslint/eslint-plugin": "4.6.1",
|
|
64
64
|
"@typescript-eslint/parser": "4.6.1",
|
|
65
65
|
"chai": "^3.5.0",
|
|
66
66
|
"chai-as-promised": "^6.0.0",
|
|
67
67
|
"eslint": "7.12.1",
|
|
68
|
-
"
|
|
68
|
+
"jest": "^29.7.0",
|
|
69
69
|
"nyc": "14.1.x",
|
|
70
70
|
"prettier": "^2.8.8",
|
|
71
71
|
"pretty-quick": "^3.1.3",
|
|
72
72
|
"rollup": "^2.79.1",
|
|
73
73
|
"sinon": "^9.2.4",
|
|
74
|
+
"ts-jest": "^29.1.1",
|
|
74
75
|
"terser": "^5.19.2",
|
|
75
76
|
"ts-node": "10.8.2",
|
|
76
77
|
"tslib": "^2.6.2",
|