@autofleet/zehut 4.3.1 → 4.3.4-beta-2c88118a.0
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/lib/index.cjs +2 -2
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +83 -6
- package/lib/index.d.ts +83 -6
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/lib/index.cjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var P=require('@autofleet/outbreak'),T=require('jsonwebtoken'),xe=require('node-cache'),$=require('object-hash'),v=require('moment'),F=require('@autofleet/network');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var P__namespace=/*#__PURE__*/_interopNamespace(P);var T__default=/*#__PURE__*/_interopDefault(T);var xe__default=/*#__PURE__*/_interopDefault(xe);var $__default=/*#__PURE__*/_interopDefault($);var v__default=/*#__PURE__*/_interopDefault(v);var F__default=/*#__PURE__*/_interopDefault(F);var {DEPRECATED_JWT_SECRET:de,JWT_NEW_SECRET:ue,DEPRECATED_REFRESH_JWT_SECRET:pe,REFRESH_JWT_SECRET:me,DEPRECATION_UNIX_TIMESTAMP:fe}=process.env,L=(t,e,s)=>{let r=v__default.default(parseInt(fe,10)*1e3);try{let o;if(t){let{iat:i}=T__default.default.decode(t);o=v__default.default(i*1e3);}else o=v__default.default();return o.isBefore(r)?e:s}catch{return s}},le=t=>L(t,pe,me),_=t=>L(t,de,ue);var R=t=>t.replace("Bearer ",""),O=(t,e)=>{let s=R(t);return T__default.default.verify(s,_(s))};var Ee="00000000-0000-0000-0000-000000000000",Pe="ffffffff-ffff-ffff-ffff-ffffffffffff",h="[0-9a-f]",ge="[1-8]",he=new RegExp(`^(?:${h}{8}-${h}{4}-${ge}${h}{3}-[89ab]${h}{3}-${h}{12}|${Ee}|${Pe})$`,"i");function M(t){return typeof t=="string"&&he.test(t)}var B=10,j=process.env.API_GATEWAY_URL||"https://api.autofleet.io",w=new F__default.default({serviceName:"IDENTITY_MS",retries:3,retryCondition:()=>true,cache:process.env.NODE_ENV!=="test"?{maxAge:B*1e3}:void 0}),S=new F__default.default({baseURL:j,serviceUrl:j,retries:3,retryCondition:()=>true,cache:process.env.NODE_ENV!=="test"?{maxAge:B*1e3}:void 0});var l="x-af-elevated-permissions",y="x-af-context-ids",m=new xe__default.default({stdTTL:10}),J=(t,e)=>{let s={...t,fleets:{...t?.fleets},businessModels:{...t?.businessModels},demandSources:{...t?.demandSources}};for(let r of e)Object.keys(r).forEach(o=>{s[o]??={},Object.entries(r[o]).forEach(([i,n])=>{s[o][i]=(s[o][i]||[]).concat(n);});});return s};typeof Symbol.dispose!="symbol"&&Object.defineProperty(Symbol,"dispose",{__proto__:null,configurable:false,enumerable:false,value:Symbol.for("nodejs.dispose"),writable:false});typeof Symbol.asyncDispose!="symbol"&&Object.defineProperty(Symbol,"asyncDispose",{__proto__:null,configurable:false,enumerable:false,value:Symbol.for("nodejs.asyncDispose"),writable:false});var u=class{constructor(e,s,r,o){this.id=e;this.accountType=s;this.contextIds=o;this.privateElevatedPermissionsHash=new Map;this.appPermission={};this.emptyUser=!!e,r&&this.privateElevatedPermissionsHash.set(Symbol("initial"),r);}async getUserPermissions(){if(!this.id)return;if(this.privatePermissions)return this.privatePermissions;let e=$__default.default({id:this.id,contextIds:this.contextIds}),s=m.get(e);return s||({data:s}=await w.get(`/api/v1/users/${this.id}/authorization-payload`,{params:{contextIds:this.contextIds}}),m.set(e,s)),this.accountType=s.accountType,this.privatePermissions=s,this.privatePermissions}async useCustomPermissionLoader(e){if(!this.id)return;if(this.privatePermissions)return this.privatePermissions;let s=this.id,r=m.get(s);if(r)return this.privatePermissions=r,r;let o=await e(this.id);return m.set(s,o),this.privatePermissions=o,this.privatePermissions}get businessModels(){return this.getUserProperty("businessModels")}get fleets(){return this.getUserProperty("fleets")}get demandSources(){return this.getUserProperty("demandSources")}getUserProperty(e){if(!this.privatePermissions)throw new Error(`Cannot get ${e} without calling (async) getUserPermissions before`);return Object.keys(this.privatePermissions[e]||{})}get elevatedPermissions(){return J(void 0,this.privateElevatedPermissionsHash.values())}get permissions(){if(!this.privatePermissions)throw new Error("Cannot get permissions without calling (async) getUserPermissions before");return J(this.privatePermissions,this.privateElevatedPermissionsHash.values())}elevatePermissions(e){let s=Symbol();Object.values(e).forEach(c=>{Object.keys(c).forEach(a=>{if(!M(a))throw new Error(`Entity id on elevatePermissions is not a valid UUID, provided: ${a}`)});});let r=P.getCurrentContext();if(!r)throw new Error("Cannot find current user cross services trace");let o=JSON.parse(r.context[l]||"{}"),i=Object.assign(o,e);this.privateElevatedPermissionsHash.set(s,i),r.context.set(l,JSON.stringify(this.elevatedPermissions));let n=()=>{this.privateElevatedPermissionsHash.delete(s),r.context.set(l,JSON.stringify(this.elevatedPermissions));};return n[Symbol.dispose]=n,n}async getUserPermissionsLegacy(){if(!this.id)return;if(this.privatePermissionsLegacy)return this.privatePermissionsLegacy;let e=$__default.default({id:this.id,contextIds:this.contextIds,legacy:true}),s=m.get(e);return s||({data:s}=await w.get(`/api/v1/users/${this.id}/authorization-payload-legacy`,{params:{contextIds:this.contextIds}}),m.set(e,s)),this.privatePermissionsLegacy=s,this.privatePermissionsLegacy}get permissionsLegacy(){if(!this.privatePermissionsLegacy)throw new Error("Cannot get permissionsLegacy without calling (async) getUserPermissionsLegacy before");return this.privatePermissionsLegacy}async getUserAppPermissions(e,s){if(!this.id||!e||!s)return;let r=this.appPermission[e];if(r)return r;let o=`${this.id}:${e}`,i=m.get(o);if(i)return this.appPermission[e]=i,i;let{data:n}=await S.post(`/api/v1/apps/${e}/get-user-payload`,{userId:this.id},{headers:{"x-autofleet-apps-secret":s}});return m.set(o,n),this.appPermission[e]=n,this.appPermission[e]}};var W=async(t,e)=>{let{data:s}=await S.post("/api/v1/auth",{bearer:t,appId:e});return s};var E=class extends Error{constructor(){super(...arguments);this.name="AppDoesNotExist";this.message="app does not exist";}};var G="identity-ms",X="accessToken",f="userObject",x="x-af-user-id",H="X-IAF-ORIGIN-SERVICE",A="x-af-user-permissions",z=H.toLowerCase(),V="x-autofleet-apps-secret";var b=async(t,e)=>{let s=e[H]||e[z]||"";if(!Array.isArray(s)&&s.toLowerCase()===G)return;let{eagerLoadUserPermissions:r,eagerLoadUserPermissionsLegacy:o,customPermissionLoader:i}=t,n=e[x];if(!n||Array.isArray(n))return;let c=e[l]?.length>0?JSON.parse(e[l]):{},a=e?.[y]?.split(","),d=new u(n,"user",c,a);return r&&(i?await d.useCustomPermissionLoader(i):await d.getUserPermissions()),o&&await d.getUserPermissionsLegacy(),P.getCurrentContext().nonHeaderContext?.set(f,d),d};var Y=(t={})=>async(e,s,r)=>{try{let o=await b(t,e.headers);o&&(e.user=o,e.headers[A]=o),r();}catch{s.status(401).json({error:"cannot authenticate user"});}},Z=(t={})=>async(e,s,r)=>{let{eagerLoadUserPermissions:o,eagerLoadUserPermissionsLegacy:i,returnErrorIfNoToken:n}=t,c;if(e.headers.authorization){try{c=await O(e.headers.authorization);}catch(g){g instanceof T__default.default.TokenExpiredError?s.status(401).json({errors:["Access token expired"]}):g instanceof T__default.default.JsonWebTokenError?s.status(400).json({errors:[g.message]}):s.status(500).json({errors:["Server error while parsing token"]});return}let a=c?.user?.id;a&&(e.headers[x]=a);let d=e.headers?.[y]?.split(","),p=new u(a,c?.user?.accountType,void 0,d);(o||i)&&await Promise.all([o&&p.getUserPermissions(),i&&p.getUserPermissionsLegacy()]),e.user=p,P.getCurrentContext().nonHeaderContext?.set(f,p),e.headers[A]=p;}else if(n){s.status(401).json({errors:["No token provided"]});return}r();},Q=t=>async(e,s,r)=>{let{appId:o,clientSecret:i}=t,n;if(!e.headers.authorization){s.status(401).json({errors:["No token provided"]});return}try{if(n=await W(e.headers.authorization,o),!n)throw new E}catch(p){if(p instanceof T__default.default.TokenExpiredError){s.status(401).json({errors:["Access token expired"]});return}if([T__default.default.JsonWebTokenError,E].some(g=>p instanceof g)){s.status(400).json({errors:[p.message]});return}s.status(500).json({errors:["Server error while parsing token"]});return}let c=n?.userId;c&&(e.headers[x]=c);let a=new u(c);o&&(e.headers[V]=i,await a.getUserAppPermissions(o,i)),e.user=a;let d=P.getCurrentContext().nonHeaderContext;d?.set(f,a),d?.set(X,R(e.headers.authorization)),e.headers[A]=a,r();},q=async(t,e,s)=>{await t.user.getUserPermissions(),s();},ee=t=>t.headers.authorization?O(t.headers.authorization):null,te=async(t,e)=>{let s=new u(e);await s.getUserPermissions(),t??=P.newTrace(P.traceTypes.RABBIT),t.nonHeaderContext.set(f,s);},se=u;var N=(t,e,s)=>{t.decorateRequest("user",void 0),t.addHook("onRequest",async(r,o)=>{try{let i=await b(e,r.headers);i&&(r.user=i);}catch{o.status(401).send({error:"cannot authenticate user"});}}),s();};N[Symbol.for("skip-override")]=true;var I=()=>P.getCurrentContext().nonHeaderContext?.get(f),D=()=>I()?.id,k=(t,e)=>!D()||Object.hasOwn(I().permissions[e],t),re=t=>k(t,"fleets"),oe=t=>k(t,"businessModels"),ie=t=>k(t,"demandSources");var C=class extends Error{constructor(s=null,r="UnauthorizedAccessError"){super(r);this.user=s;this.name="UnauthorizedAccessError";}};var U={NONE:"NONE",BASIC:"BASIC",JWT:"JWT"},ne={[U.NONE]:()=>{},[U.BASIC]:t=>{let{username:e,password:s}=t;return `Basic ${Buffer.from(`${e}:${s}`).toString("base64")}`},[U.JWT]:t=>{let{secret:e}=t;if(e)return `Bearer ${T__default.default.sign({},e,{expiresIn:10})}`}},ae=t=>{let e=t?.method;if(!(!e||!ne[e]))return ne[e](t)};var Ce=P__namespace.getCurrentContext,bt=({outbreakOptions:t={},logger:e}={})=>{P__namespace.default({headersPrefix:"x-af",contextMiddlewareGetter:e?.addContextMiddleware,...t});},{traceTypes:ve,newTrace:_e}=P__namespace;var Tt={traceTypes:ve,newTrace:_e,User:se,middleware:Y,middlewareWithDecode:Z,eagerLoadPermissionsMiddleware:q,getCurrentPayload:Ce,getDecodedBearer:ee,checkFleetPermission:re,checkBusinessModelPermission:oe,checkDemandSourcePermission:ie,isUserExist:D,getUser:I,UnauthorizedAccessError:C,appMiddleware:Q,createOrSetRabbitTrace:te,outbreak:P__namespace,AUTHORIZATION_METHODS:U,getAuthorizationHeader:ae,CONTEXTS_IDS_HEADER:y,authFromUserIdHeaderPlugin:N};
|
|
2
|
-
exports.outbreak=
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var I=require('@autofleet/outbreak'),N=require('jsonwebtoken'),Me=require('node-cache'),Q=require('object-hash'),D=require('moment'),X=require('@autofleet/network');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var I__namespace=/*#__PURE__*/_interopNamespace(I);var N__default=/*#__PURE__*/_interopDefault(N);var Me__default=/*#__PURE__*/_interopDefault(Me);var Q__default=/*#__PURE__*/_interopDefault(Q);var D__default=/*#__PURE__*/_interopDefault(D);var X__default=/*#__PURE__*/_interopDefault(X);var Ue=Object.defineProperty;var xe=(t,e)=>{for(var s in e)Ue(t,s,{get:e[s],enumerable:true});};var {DEPRECATED_JWT_SECRET:Ae,JWT_NEW_SECRET:Te,DEPRECATED_REFRESH_JWT_SECRET:_e,REFRESH_JWT_SECRET:Ce,DEPRECATION_UNIX_TIMESTAMP:Ne}=process.env,J=(t,e,s)=>{let r=D__default.default(parseInt(Ne,10)*1e3);try{let o;if(t){let{iat:i}=N__default.default.decode(t);o=D__default.default(i*1e3);}else o=D__default.default();return o.isBefore(r)?e:s}catch{return s}},be=t=>J(t,_e,Ce),k=t=>J(t,Ae,Te);var L=t=>t.replace("Bearer ",""),H=(t,e)=>{let s=L(t);return N__default.default.verify(s,k(s))};var De="00000000-0000-0000-0000-000000000000",ke="ffffffff-ffff-ffff-ffff-ffffffffffff",S="[0-9a-f]",Le="[1-8]",He=new RegExp(`^(?:${S}{8}-${S}{4}-${Le}${S}{3}-[89ab]${S}{3}-${S}{12}|${De}|${ke})$`,"i");function V(t){return typeof t=="string"&&He.test(t)}var K=10,G=process.env.API_GATEWAY_URL||"https://api.autofleet.io",O=new X__default.default({serviceName:"IDENTITY_MS",retries:3,retryCondition:()=>true,cache:process.env.NODE_ENV!=="test"?{maxAge:K*1e3}:void 0}),T=new X__default.default({baseURL:G,serviceUrl:G,retries:3,retryCondition:()=>true,cache:process.env.NODE_ENV!=="test"?{maxAge:K*1e3}:void 0});var h="x-af-elevated-permissions",f="x-af-context-ids",E=new Me__default.default({stdTTL:10}),Y=(t,e)=>{let s={...t,fleets:{...t?.fleets},businessModels:{...t?.businessModels},demandSources:{...t?.demandSources}};for(let r of e)Object.keys(r).forEach(o=>{s[o]??={},Object.entries(r[o]).forEach(([i,n])=>{s[o][i]=(s[o][i]||[]).concat(n);});});return s};typeof Symbol.dispose!="symbol"&&Object.defineProperty(Symbol,"dispose",{__proto__:null,configurable:false,enumerable:false,value:Symbol.for("nodejs.dispose"),writable:false});typeof Symbol.asyncDispose!="symbol"&&Object.defineProperty(Symbol,"asyncDispose",{__proto__:null,configurable:false,enumerable:false,value:Symbol.for("nodejs.asyncDispose"),writable:false});var p=class{constructor(e,s,r,o){this.id=e;this.accountType=s;this.contextIds=o;this.privateElevatedPermissionsHash=new Map;this.appPermission={};this.emptyUser=!!e,r&&this.privateElevatedPermissionsHash.set(Symbol("initial"),r);}async getUserPermissions(){if(!this.id)return;if(this.privatePermissions)return this.privatePermissions;let e=Q__default.default({id:this.id,contextIds:this.contextIds}),s=E.get(e);return s||({data:s}=await O.get(`/api/v1/users/${this.id}/authorization-payload`,{params:{contextIds:this.contextIds}}),E.set(e,s)),this.accountType=s.accountType,this.privatePermissions=s,this.privatePermissions}async useCustomPermissionLoader(e){if(!this.id)return;if(this.privatePermissions)return this.privatePermissions;let s=this.id,r=E.get(s);if(r)return this.privatePermissions=r,r;let o=await e(this.id);return E.set(s,o),this.privatePermissions=o,this.privatePermissions}get businessModels(){return this.getUserProperty("businessModels")}get fleets(){return this.getUserProperty("fleets")}get demandSources(){return this.getUserProperty("demandSources")}getUserProperty(e){if(!this.privatePermissions)throw new Error(`Cannot get ${e} without calling (async) getUserPermissions before`);return Object.keys(this.privatePermissions[e]||{})}get elevatedPermissions(){return Y(void 0,this.privateElevatedPermissionsHash.values())}get permissions(){if(!this.privatePermissions)throw new Error("Cannot get permissions without calling (async) getUserPermissions before");return Y(this.privatePermissions,this.privateElevatedPermissionsHash.values())}elevatePermissions(e){let s=Symbol();Object.values(e).forEach(c=>{Object.keys(c).forEach(a=>{if(!V(a))throw new Error(`Entity id on elevatePermissions is not a valid UUID, provided: ${a}`)});});let r=I.getCurrentContext();if(!r)throw new Error("Cannot find current user cross services trace");let o=JSON.parse(r.context[h]||"{}"),i=Object.assign(o,e);this.privateElevatedPermissionsHash.set(s,i),r.context.set(h,JSON.stringify(this.elevatedPermissions));let n=()=>{this.privateElevatedPermissionsHash.delete(s),r.context.set(h,JSON.stringify(this.elevatedPermissions));};return n[Symbol.dispose]=n,n}async getUserPermissionsLegacy(){if(!this.id)return;if(this.privatePermissionsLegacy)return this.privatePermissionsLegacy;let e=Q__default.default({id:this.id,contextIds:this.contextIds,legacy:true}),s=E.get(e);return s||({data:s}=await O.get(`/api/v1/users/${this.id}/authorization-payload-legacy`,{params:{contextIds:this.contextIds}}),E.set(e,s)),this.privatePermissionsLegacy=s,this.privatePermissionsLegacy}get permissionsLegacy(){if(!this.privatePermissionsLegacy)throw new Error("Cannot get permissionsLegacy without calling (async) getUserPermissionsLegacy before");return this.privatePermissionsLegacy}async getUserAppPermissions(e,s){if(!this.id||!e||!s)return;let r=this.appPermission[e];if(r)return r;let o=`${this.id}:${e}`,i=E.get(o);if(i)return this.appPermission[e]=i,i;let{data:n}=await T.post(`/api/v1/apps/${e}/get-user-payload`,{userId:this.id},{headers:{"x-autofleet-apps-secret":s}});return E.set(o,n),this.appPermission[e]=n,this.appPermission[e]}};var Z=async(t,e)=>{let{data:s}=await T.post("/api/v1/auth",{bearer:t,appId:e});return s};var R=class extends Error{constructor(){super(...arguments);this.name="AppDoesNotExist";this.message="app does not exist";}};var q="identity-ms",ee="accessToken",P="userObject",U="x-af-user-id",M="X-IAF-ORIGIN-SERVICE",_="x-af-user-permissions",se=M.toLowerCase(),te="x-autofleet-apps-secret";var C=async(t,e)=>{let s=e[M]||e[se]||"";if(!Array.isArray(s)&&s.toLowerCase()===q)return;let{eagerLoadUserPermissions:r,eagerLoadUserPermissionsLegacy:o,customPermissionLoader:i}=t,n=e[U];if(!n||Array.isArray(n))return;let c=e[h]?.length>0?JSON.parse(e[h]):{},a=e?.[f]?.split(","),m=new p(n,"user",c,a);return r&&(i?await m.useCustomPermissionLoader(i):await m.getUserPermissions()),o&&await m.getUserPermissionsLegacy(),I.getCurrentContext().nonHeaderContext?.set(P,m),m};var oe=(t={})=>async(e,s,r)=>{try{let o=await C(t,e.headers);o&&(e.user=o,e.headers[_]=o),r();}catch{s.status(401).json({error:"cannot authenticate user"});}},ie=(t={})=>async(e,s,r)=>{let{eagerLoadUserPermissions:o,eagerLoadUserPermissionsLegacy:i,returnErrorIfNoToken:n}=t,c;if(e.headers.authorization){try{c=await H(e.headers.authorization);}catch(d){d instanceof N__default.default.TokenExpiredError?s.status(401).json({errors:["Access token expired"]}):d instanceof N__default.default.JsonWebTokenError?s.status(400).json({errors:[d.message]}):s.status(500).json({errors:["Server error while parsing token"]});return}let a=c?.user?.id;a&&(e.headers[U]=a);let m=e.headers?.[f]?.split(","),u=new p(a,c?.user?.accountType,void 0,m);(o||i)&&await Promise.all([o&&u.getUserPermissions(),i&&u.getUserPermissionsLegacy()]),e.user=u,I.getCurrentContext().nonHeaderContext?.set(P,u),e.headers[_]=u;}else if(n){s.status(401).json({errors:["No token provided"]});return}r();},ne=t=>async(e,s,r)=>{let{appId:o,clientSecret:i}=t,n;if(!e.headers.authorization){s.status(401).json({errors:["No token provided"]});return}try{if(n=await Z(e.headers.authorization,o),!n)throw new R}catch(u){if(u instanceof N__default.default.TokenExpiredError){s.status(401).json({errors:["Access token expired"]});return}if([N__default.default.JsonWebTokenError,R].some(d=>u instanceof d)){s.status(400).json({errors:[u.message]});return}s.status(500).json({errors:["Server error while parsing token"]});return}let c=n?.userId;c&&(e.headers[U]=c);let a=new p(c);o&&(e.headers[te]=i,await a.getUserAppPermissions(o,i)),e.user=a;let m=I.getCurrentContext().nonHeaderContext;m?.set(P,a),m?.set(ee,L(e.headers.authorization)),e.headers[_]=a,r();},ae=async(t,e,s)=>{await t.user.getUserPermissions(),s();},ce=t=>t.headers.authorization?H(t.headers.authorization):null,ue=async(t,e)=>{let s=new p(e);await s.getUserPermissions(),t??=I.newTrace(I.traceTypes.RABBIT),t.nonHeaderContext.set(P,s);},me=p;var F=(t,e,s)=>{t.decorateRequest("user",void 0),t.addHook("onRequest",async(r,o)=>{try{let i=await C(e,r.headers);i&&(r.user=i);}catch{o.status(401).send({error:"cannot authenticate user"});}}),s();};F[Symbol.for("skip-override")]=true;var g=()=>I.getCurrentContext().nonHeaderContext?.get(P),B=()=>g()?.id,j=(t,e)=>!B()||Object.hasOwn(g().permissions[e],t),de=t=>j(t,"fleets"),pe=t=>j(t,"businessModels"),le=t=>j(t,"demandSources");var b=class extends Error{constructor(s=null,r="UnauthorizedAccessError"){super(r);this.user=s;this.name="UnauthorizedAccessError";}};var x={NONE:"NONE",BASIC:"BASIC",JWT:"JWT"},Ee={[x.NONE]:()=>{},[x.BASIC]:t=>{let{username:e,password:s}=t;return `Basic ${Buffer.from(`${e}:${s}`).toString("base64")}`},[x.JWT]:t=>{let{secret:e}=t;if(e)return `Bearer ${N__default.default.sign({},e,{expiresIn:10})}`}},fe=t=>{let e=t?.method;if(!(!e||!Ee[e]))return Ee[e](t)};var z={};xe(z,{default:()=>rs,middlewares:()=>Re,sdk:()=>he});var $=class{constructor(e){this.cache=e||new Me__default.default({stdTTL:10});}async getUserPermissions(e,s){try{let r=o=>`perm-${e}-${o}`;return await this.cache.mget(s.map(r))}catch{return {}}}async setUserPermissions(e,s,r){try{let o=n=>`perm-${e}-${n}`,i=Object.entries(s).map(([n,c])=>({key:o(n),val:c,ttl:r??10}));return await this.cache.mset(i),{success:!0}}catch{return {success:false}}}async getSeenPermissions(e,s,r){try{let o=r.sort().join(","),i=n=>`seen-${e}-${n}-${o}`;return await this.cache.mget(s.map(i))}catch{return {}}}async setSeenPermissions(e,s,r,o){try{let i=r.sort().join(","),n=a=>`seen-${e}-${a}-${i}`,c=s.map(a=>({key:n(a),val:!0,ttl:o??10}));return await this.cache.mset(c),{success:!0}}catch{return {success:false}}}},v=new $;var y={AND:"and",OR:"or"},l={USER_NOT_FOUND:"USER_NOT_FOUND",INSUFFICIENT_PERMISSIONS:"INSUFFICIENT_PERMISSIONS",VALIDATION_ERROR:"VALIDATION_ERROR",API_ERROR:"API_ERROR",NO_REQUIRED_PERMISSIONS:"NO_REQUIRED_PERMISSIONS",UNAUTHORIZED:"UNAUTHORIZED",BAD_REQUEST:"BAD_REQUEST",INTERNAL_ERROR:"INTERNAL_ERROR"},A={USER_NOT_FOUND:"User not found",INSUFFICIENT_PERMISSIONS:"User does not have sufficient permissions",VALIDATION_ERROR:"Validation error occurred",API_ERROR:"API error occurred",NO_REQUIRED_PERMISSIONS:"No required permissions provided for evaluation",UNAUTHORIZED:"User is not authorized to perform this action",BAD_REQUEST:"Bad request, please check the input parameters",INTERNAL_ERROR:"Internal server error occurred while checking permissions"};var ge=(t,e,s)=>{let r=new Set(t),o=e.filter(i=>r.has(i));return s===y.AND?o.length===e.length:o.length>0};var Ve=(t,e)=>{let s=Object.values(t);return e?s.every(r=>r.hasRequiredPermissions):s.some(r=>r.hasRequiredPermissions)};var Ge=t=>{let e=[];return t?.length||e.push("contextIds cannot be empty"),e},Pe=(t,e,s,r)=>({isAuthorized:false,error:t,resolvedPermissions:{},requiredPermissions:e,contextIds:s,...r&&{message:r}}),Xe=async(t,e,s)=>{let r={},o=[];Object.entries(e).forEach(([i,n])=>{n?.permissions&&(n.hasRequiredPermissions?r[i]=n.permissions:o.push(i));}),Object.keys(r).length>0&&await v.setUserPermissions(t,r),o.length>0&&await v.setSeenPermissions(t,o,s);},Ke=async(t,e,s)=>{let r=await v.getSeenPermissions(t,e,s);return e.filter(o=>!r[`seen-${t}-${o}-${s.sort().join(",")}`])},Qe=(t,e)=>{let s=t.filter(o=>!e.includes(o)),r={};return s.forEach(o=>{r[o]={permissions:[],hasRequiredPermissions:false};}),r},Ye=(t,e,s)=>{let r={};return Object.keys(t||{}).length&&Object.entries(t).forEach(([o,i])=>{let n=ge(i,e,s);r[o]={permissions:i,hasRequiredPermissions:n};}),r},Ze=async(t,e,s,r)=>{let o=await O.post("/api/v1/permissions/resolve",{userId:t,contextIds:e,requiredPermissions:s},{timeout:r.timeout}),{data:i}=o;if(!Object.keys(i||{}).length)throw new Error("Failed to resolve permissions");if(r.permissionsEvaluationOperator===y.AND)return i;let n={};return Object.entries(i).forEach(([c,a])=>{let m=a?.permissions||[],u=ge(m,s,r.permissionsEvaluationOperator);n[c]={permissions:m,hasRequiredPermissions:u};}),n},qe=(t,e,s,r)=>{let o=Ge(t);return o.length?Pe(l.VALIDATION_ERROR,e,t,o.join(", ")):s?e?.length?null:(r?.info("No requiredPermissions provided",{userId:s,contextIds:t}),{isAuthorized:false,userId:s,resolvedPermissions:{},requiredPermissions:e,contextIds:t,error:l.NO_REQUIRED_PERMISSIONS}):(r?.warn("User not found in context, cannot check permissions",{contextIds:t,requiredPermissions:e}),Pe(l.USER_NOT_FOUND,e,t))},es=async(t,e,s,r)=>{let o=await v.getUserPermissions(t,e),i=Ye(o,s,r.permissionsEvaluationOperator),n={...i},c=e.filter(u=>!i[u]),a=await Ke(t,c,s),m=Qe(c,a);if(n={...n,...m},a.length){let u=await Ze(t,a,s,r);n={...n,...u},await Xe(t,u,s);}return n},w=async({requiredPermissions:t,contextIds:e,logger:s,userId:r,options:{requireAll:o=true,permissionsEvaluationOperator:i=y.AND,timeout:n=1e4}})=>{let c=r||g()?.id||null,a=qe(e,t,c,s);if(a)return a;let m=await es(c,e,t,{permissionsEvaluationOperator:i,timeout:n}),u=Ve(m,o);return s?.info("Resolved permissions",{userId:c,requiredPermissions:t,isAuthorized:u,requireAll:o,permissionsEvaluationOperator:i,contextIds:e}),{isAuthorized:u,userId:c,resolvedPermissions:m,requiredPermissions:t,contextIds:e,...u?{}:{error:l.INSUFFICIENT_PERMISSIONS}}};var ss=t=>{let e=t.headers?.[f]?.split(",")||[],s=t.query?.contextIds?.split(",")||[],r=t.body?.contextIds||[];return Array.from(new Set([...e,...s,...r])).filter(Boolean)},ts=(t,e,s,r,o,i,n,c,a)=>r?(c?.error(e,{url:i.url,method:i.method,requiredPermissions:a?.requiredPermissions||[],...a}),o.status(s).json({error:t,message:e,...a?.requiredPermissions&&{requiredPermissions:a.requiredPermissions}})):(c?.warn(e,{url:i.url,method:i.method,requiredPermissions:a?.requiredPermissions||[],...a}),n()),ye=(t,e={enforce:false,requireAll:true,permissionsEvaluationOperator:y.AND})=>async(s,r,o)=>{try{let{logger:i,enforce:n,requireAll:c,permissionsEvaluationOperator:a}=e,m=(Ie,Se,Oe)=>ts(Ie,Se,Oe,n,r,s,o,i,{requiredPermissions:t}),u=g();if(!u?.id)return m(l.UNAUTHORIZED,A.UNAUTHORIZED,401);let d=ss(s);if(!d?.length)return m(l.BAD_REQUEST,A.BAD_REQUEST,400);let W=await w({requiredPermissions:t,contextIds:d,logger:i,userId:u.id,options:{requireAll:c??!0,permissionsEvaluationOperator:a??y.AND,timeout:1e4}});return W.isAuthorized?(i?.info("User has required permissions",{userId:u.id,requiredPermissions:t,contextIds:d,url:s.url,method:s.method}),o()):n?r.status(403).json({error:l.INSUFFICIENT_PERMISSIONS,message:A.INSUFFICIENT_PERMISSIONS,required:t,contexts:d,userId:W.userId}):(i?.warn("User does not have required permissions, skipping enforcement",{userId:u.id,requiredPermissions:t,contextIds:d,url:s.url,method:s.method}),o())}catch(i){return e.logger?.error("Error in requirePermissions middleware",{error:i,requiredPermissions:t,url:s.url,method:s.method}),e.enforce?r.status(500).json({error:l.INTERNAL_ERROR,message:A.INTERNAL_ERROR}):(e.logger?.error("Error during permission check, skipping enforcement",{error:i,url:s.url,method:s.method}),o())}};var he={evaluatePermissions:w},Re={requirePermissions:ye},rs={sdk:he,middlewares:Re};var os=I__namespace.getCurrentContext,gt=({outbreakOptions:t={},logger:e}={})=>{I__namespace.default({headersPrefix:"x-af",contextMiddlewareGetter:e?.addContextMiddleware,...t});},{traceTypes:is,newTrace:ns}=I__namespace;var yt={traceTypes:is,newTrace:ns,User:me,middleware:oe,middlewareWithDecode:ie,eagerLoadPermissionsMiddleware:ae,getCurrentPayload:os,getDecodedBearer:ce,checkFleetPermission:de,checkBusinessModelPermission:pe,checkDemandSourcePermission:le,isUserExist:B,getUser:g,UnauthorizedAccessError:b,appMiddleware:ne,createOrSetRabbitTrace:ue,outbreak:I__namespace,AUTHORIZATION_METHODS:x,getAuthorizationHeader:fe,CONTEXTS_IDS_HEADER:f,authFromUserIdHeaderPlugin:F,permissions:z};
|
|
2
|
+
exports.outbreak=I__namespace;exports.AUTHORIZATION_METHODS=x;exports.CONTEXTS_IDS_HEADER=f;exports.UnauthorizedAccessError=b;exports.User=me;exports.appMiddleware=ne;exports.authFromUserIdHeaderPlugin=F;exports.checkBusinessModelPermission=pe;exports.checkDemandSourcePermission=le;exports.checkFleetPermission=de;exports.createOrSetRabbitTrace=ue;exports.default=yt;exports.eagerLoadPermissionsMiddleware=ae;exports.enableTracing=gt;exports.getAuthorizationHeader=fe;exports.getCurrentPayload=os;exports.getDecodedBearer=ce;exports.getRefreshTokenSecret=be;exports.getTokenSecret=k;exports.getUser=g;exports.isUserExist=B;exports.middleware=oe;exports.middlewareWithDecode=ie;exports.newTrace=ns;exports.permissions=z;exports.traceTypes=is;//# sourceMappingURL=index.cjs.map
|
|
3
3
|
//# sourceMappingURL=index.cjs.map
|
package/lib/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/secret-getter.ts","../src/utils.ts","../src/services.ts","../src/user/ApiUser.ts","../src/app-auth.ts","../src/exceptions/appDoesNotExist.ts","../src/user/const.ts","../src/user/common.ts","../src/user/index.ts","../src/user/fastify.ts","../src/check-permission.ts","../src/errors.ts","../src/authorization.ts","../src/index.ts"],"names":["DEPRECATED_JWT_SECRET","JWT_NEW_SECRET","DEPRECATED_REFRESH_JWT_SECRET","REFRESH_JWT_SECRET","DEPRECATION_UNIX_TIMESTAMP","getRelevantSecret","token","deprecatedSecret","newSecret","deprecationTime","moment","unixTime","iat","jwt","getRefreshTokenSecret","getTokenSecret","getAuthFromBearer","bearer","decodeBearer","appSecret","EMPTY_UUID","FULL_UUID","VALID_CHARS_REGEX","UUID_VERSION_REGEX","UUID_REGEX","validateUUID","uuid","CACHE_LIFETIME_IN_SEC","apiGwUrl","IdentityNetwork","Network","AutofleetApiNetwork","ELEVATED_PERMISSIONS_HEADER","CONTEXTS_IDS_HEADER","userCache","NodeCache","mergePermissions","target","sources","permissions","source","entityType","entityId","perms","ApiUser","id","accountType","elevatedPermissions","contextIds","cacheKey","objectHash","data","customPermissionLoader","cachedResult","key","addedPermissions","elevationId","entityIds","currentUserTrace","getCurrentContext","currentElevation","newElevation","cleanup","appId","clientSecret","currentAppPermission","decodeAppBearer","decoded","AppDoesNotExist","IDENTITY_MS","ACCESS_TOKEN","USER_OBJECT","USER_TRACING_HEADER","ORIGIN_HEADER","USER_PERMISSIONS_HEADER","LOWER_CASE_ORIGIN_HEADER","AUTOFLEET_APPS_SECRET_HEADER","authFromUserIdHeader","options","headers","originHeader","eagerLoadUserPermissions","eagerLoadUserPermissionsLegacy","userId","elevatedPermissionsFromHeader","userObject","middleware","req","res","next","middlewareWithDecode","returnErrorIfNoToken","e","appMiddleware","Err","currentTraceContext","eagerLoadPermissionsMiddleware","getDecodedBearer","createOrSetRabbitTrace","trace","newTrace","traceTypes","user_default","authFromUserIdHeaderPlugin","fastify","done","request","reply","user","getUser","isUserExist","checkUserPermissions","checkFleetPermission","fleetId","checkBusinessModelPermission","businessModelId","checkDemandSourcePermission","demandSourceId","UnauthorizedAccessError","message","AUTHORIZATION_METHODS","AUTHORIZATION_ACTIONS","authorizationSettings","username","password","secret","getAuthorizationHeader","authorizationMethod","getCurrentPayload","P","enableTracing","outbreakOptions","logger","outbreak","index_default"],"mappings":"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","file":"index.cjs","sourcesContent":["import jwt from 'jsonwebtoken';\nimport moment from 'moment';\n\nconst {\n DEPRECATED_JWT_SECRET, JWT_NEW_SECRET,\n DEPRECATED_REFRESH_JWT_SECRET, REFRESH_JWT_SECRET,\n DEPRECATION_UNIX_TIMESTAMP,\n} = process.env;\n\nconst getRelevantSecret = (token: string | undefined, deprecatedSecret: string, newSecret: string): string => {\n const deprecationTime = moment(parseInt(DEPRECATION_UNIX_TIMESTAMP, 10) * 1000);\n try {\n let unixTime: moment.Moment;\n if (token) {\n const { iat } = jwt.decode(token) as jwt.JwtPayload;\n unixTime = moment(iat * 1000);\n } else {\n unixTime = moment();\n }\n return unixTime.isBefore(deprecationTime) ? deprecatedSecret : newSecret;\n } catch (e) {\n return newSecret;\n }\n};\n\nexport const getRefreshTokenSecret = (token?: string): string => getRelevantSecret(token, DEPRECATED_REFRESH_JWT_SECRET, REFRESH_JWT_SECRET);\nexport const getTokenSecret = (token?: string): string => getRelevantSecret(token, DEPRECATED_JWT_SECRET, JWT_NEW_SECRET);\n","import type { UUID } from 'node:crypto';\nimport jwt from 'jsonwebtoken';\nimport { getTokenSecret } from './secret-getter';\n\ntype Context = Partial<Record<ContextProp | 'id', string>> & { subSystem?: SubSystemType; permissions?: string[]; entityId: string; };\n\nconst CONTEXT_PROPS = ['fleetId', 'businessModelId', 'demandSourceId'] as const;\ntype ContextProp = typeof CONTEXT_PROPS[number];\nconst CONTEXT_MAP_PROPS = {\n fleet: 'fleets',\n business: 'businessModels',\n demand: 'demandSources',\n} as const;\ntype SubSystemType = keyof typeof CONTEXT_MAP_PROPS;\ntype ContextSubSystemProp = typeof CONTEXT_MAP_PROPS[SubSystemType];\n\nexport const getAuthFromBearer = (bearer: string): string => bearer.replace('Bearer ', '');\n\nexport const decodeBearer = (bearer: string, appSecret?: string): any => {\n const token = getAuthFromBearer(bearer);\n const decoded = jwt.verify(token, appSecret || getTokenSecret(token));\n return decoded;\n};\n\nexport const parsePermissions = (contextId: string, decodedToken: { contexts: Context[]; }): { key: string; value: string; } | undefined => {\n if (!decodedToken) return undefined;\n const { contexts } = decodedToken;\n const activeContext = contexts.find((context) => context.id === contextId);\n\n const permissionsValue = `${activeContext.permissions?.map((cp) => `${cp},`)}`;\n\n return {\n key: activeContext.entityId,\n value: permissionsValue,\n };\n};\n\ntype EntitiesFromContext = { [key in ContextSubSystemProp]?: Record<string, string> };\nexport const getEntitiesFromContext = (contextId: string | undefined, decodedToken: { contexts: Context[]; }): EntitiesFromContext => {\n if (!decodedToken) return {};\n let { contexts } = decodedToken;\n if (contextId) {\n contexts = contexts.filter((context) => context.id === contextId);\n }\n\n const attributes: EntitiesFromContext = {};\n contexts.forEach((context) => {\n const prop = CONTEXT_MAP_PROPS[context.subSystem || 'business'];\n\n const permissions = parsePermissions(context.id, decodedToken);\n if (!permissions) return;\n attributes[prop] ||= {};\n attributes[prop][permissions.key] = permissions.value;\n });\n\n return attributes;\n};\n\ntype ContextAttributes = { [key in ContextProp]?: string[] };\nexport const getContextAttributes = (contextId: string | undefined, decodedToken: { contexts: Context[]; }): ContextAttributes => {\n if (!decodedToken) return {};\n let { contexts } = decodedToken;\n if (contextId) {\n contexts = contexts.filter((context) => context.id === contextId);\n }\n const attributes: ContextAttributes = {};\n contexts.forEach((context) => {\n CONTEXT_PROPS.forEach((prop) => {\n if (context[prop]) {\n attributes[prop] ||= [];\n attributes[prop].push(context[prop]);\n }\n });\n });\n return attributes;\n};\n\nconst EMPTY_UUID = '00000000-0000-0000-0000-000000000000';\nconst FULL_UUID = 'ffffffff-ffff-ffff-ffff-ffffffffffff';\nconst VALID_CHARS_REGEX = '[0-9a-f]';\nconst UUID_VERSION_REGEX = '[1-8]';\nconst UUID_REGEX = new RegExp(\n `^(?:${VALID_CHARS_REGEX}{8}-${VALID_CHARS_REGEX}{4}-${UUID_VERSION_REGEX}${VALID_CHARS_REGEX}{3}-[89ab]${VALID_CHARS_REGEX}{3}-${VALID_CHARS_REGEX}{12}|${EMPTY_UUID}|${FULL_UUID})$`,\n 'i',\n);\nexport function validateUUID(uuid: unknown): uuid is UUID {\n return typeof uuid === 'string' && UUID_REGEX.test(uuid);\n}\n","import Network from '@autofleet/network';\n\nconst CACHE_LIFETIME_IN_SEC = 10;\nconst apiGwUrl = process.env.API_GATEWAY_URL || 'https://api.autofleet.io';\n\n// eslint-disable-next-line import/prefer-default-export\nexport const IdentityNetwork = new Network({\n serviceName: 'IDENTITY_MS',\n retries: 3,\n retryCondition: () => true,\n cache: process.env.NODE_ENV !== 'test' ? {\n maxAge: CACHE_LIFETIME_IN_SEC * 1000,\n } : undefined,\n});\n\nexport const AutofleetApiNetwork = new Network({\n baseURL: apiGwUrl,\n serviceUrl: apiGwUrl,\n retries: 3,\n retryCondition: () => true,\n cache: process.env.NODE_ENV !== 'test' ? {\n maxAge: CACHE_LIFETIME_IN_SEC * 1000,\n } : undefined,\n});\n","import NodeCache from 'node-cache';\nimport objectHash from 'object-hash';\nimport { getCurrentContext } from '@autofleet/outbreak';\nimport { validateUUID } from '../utils';\nimport { AutofleetApiNetwork, IdentityNetwork } from '../services';\n\nexport type AccountType = 'client' | 'user' | 'service' | 'driver'\ninterface EntityPermissions {\n [key: string]: string[];\n}\n\nexport const ELEVATED_PERMISSIONS_HEADER = 'x-af-elevated-permissions';\nexport const CONTEXTS_IDS_HEADER = 'x-af-context-ids';\n\nexport interface UserPayload {\n businessModels: EntityPermissions;\n fleets: EntityPermissions;\n demandSources: EntityPermissions;\n businessAccounts?: EntityPermissions;\n accountType?: AccountType;\n contexts?: EntityPermissions;\n createdAt?: string;\n}\n\nexport interface PartialUserPayload {\n businessModels?: EntityPermissions;\n fleets?: EntityPermissions;\n demandSources?: EntityPermissions;\n vehicles?: EntityPermissions;\n drivers?: EntityPermissions;\n businessAccounts?: EntityPermissions;\n}\n\nconst userCache = new NodeCache({ stdTTL: 10 });\n\nconst mergePermissions = (target: UserPayload, sources: Iterable<PartialUserPayload>): UserPayload => {\n const permissions: UserPayload = {\n ...target,\n fleets: { ...target?.fleets },\n businessModels: { ...target?.businessModels },\n demandSources: { ...target?.demandSources },\n // Clone other nested objects as needed\n };\n\n // eslint-disable-next-line no-restricted-syntax\n for (const source of sources) {\n Object.keys(source).forEach((entityType) => {\n // eslint-disable-next-line no-param-reassign\n permissions[entityType] ??= {};\n Object.entries(source[entityType]!).forEach(([entityId, perms]) => {\n // eslint-disable-next-line no-param-reassign\n permissions[entityType][entityId] = (permissions[entityType][entityId] || []).concat(perms);\n });\n });\n }\n\n return permissions;\n};\n\nif (typeof Symbol.dispose !== 'symbol') {\n // Polyfill for dispose if it does not exist, based on https://github.com/nodejs/node/blob/9a9409ff1f45c968173118de4cd37dea784f8ec9/lib/internal/process/pre_execution.js#L163-L171\n Object.defineProperty(Symbol, 'dispose', {\n // @ts-expect-error: TypeScript does not recognize __proto__ as a valid property\n __proto__: null,\n configurable: false,\n enumerable: false,\n value: Symbol.for('nodejs.dispose'),\n writable: false,\n });\n}\nif (typeof Symbol.asyncDispose !== 'symbol') {\n // Polyfill for asyncDispose if it does not exist, based on https://github.com/nodejs/node/blob/9a9409ff1f45c968173118de4cd37dea784f8ec9/lib/internal/process/pre_execution.js#L174-L183\n Object.defineProperty(Symbol, 'asyncDispose', {\n // @ts-expect-error: TypeScript does not recognize __proto__ as a valid property\n __proto__: null,\n configurable: false,\n enumerable: false,\n value: Symbol.for('nodejs.asyncDispose'),\n writable: false,\n });\n}\n\nexport default class ApiUser {\n private privatePermissions: UserPayload | undefined;\n\n private readonly privateElevatedPermissionsHash = new Map<symbol, PartialUserPayload | undefined>();\n\n private privatePermissionsLegacy: any;\n\n private readonly appPermission: {[key: string]: any; } = {};\n\n public readonly emptyUser: boolean;\n\n constructor(public id? : string, public accountType?: AccountType, elevatedPermissions?: PartialUserPayload, public contextIds?: string[]) {\n this.emptyUser = !!id;\n if (elevatedPermissions) {\n this.privateElevatedPermissionsHash.set(Symbol('initial'), elevatedPermissions);\n }\n }\n\n public async getUserPermissions(): Promise<UserPayload> {\n if (!this.id) {\n return undefined;\n }\n if (this.privatePermissions) {\n return this.privatePermissions;\n }\n const cacheKey = objectHash({\n id: this.id,\n contextIds: this.contextIds,\n });\n\n let data = userCache.get<UserPayload>(cacheKey);\n\n if (!data) {\n ({ data } = await IdentityNetwork.get<UserPayload>(`/api/v1/users/${this.id}/authorization-payload`, { params: { contextIds: this.contextIds } }));\n userCache.set(cacheKey, data);\n }\n\n this.accountType = data.accountType;\n this.privatePermissions = data;\n return this.privatePermissions;\n }\n\n public async useCustomPermissionLoader(customPermissionLoader: (userId: string) => UserPayload | PromiseLike<UserPayload>): Promise<UserPayload> {\n if (!this.id) {\n return undefined;\n }\n if (this.privatePermissions) {\n return this.privatePermissions;\n }\n\n const cacheKey = this.id;\n\n const cachedResult = userCache.get<UserPayload>(cacheKey);\n if (cachedResult) {\n this.privatePermissions = cachedResult;\n return cachedResult;\n }\n\n const data = await customPermissionLoader(this.id);\n userCache.set(cacheKey, data);\n\n this.privatePermissions = data;\n return this.privatePermissions;\n }\n\n public get businessModels(): string[] {\n return this.getUserProperty('businessModels');\n }\n\n public get fleets(): string[] {\n return this.getUserProperty('fleets');\n }\n\n public get demandSources(): string[] {\n return this.getUserProperty('demandSources');\n }\n\n private getUserProperty(key: keyof UserPayload): string[] {\n if (!this.privatePermissions) {\n throw new Error(`Cannot get ${key} without calling (async) getUserPermissions before`);\n }\n return Object.keys(this.privatePermissions[key] || {});\n }\n\n public get elevatedPermissions(): UserPayload {\n return mergePermissions(undefined, this.privateElevatedPermissionsHash.values());\n }\n\n public get permissions(): UserPayload | undefined {\n if (!this.privatePermissions) {\n throw new Error('Cannot get permissions without calling (async) getUserPermissions before');\n }\n\n return mergePermissions(this.privatePermissions, this.privateElevatedPermissionsHash.values());\n }\n\n public elevatePermissions(addedPermissions: PartialUserPayload): (() => void) & { [Symbol.dispose]: () => void } {\n // @itayankri is concerned about memory consumption, so create a symbol with no description, to avoid assigning memory for the description string\n // eslint-disable-next-line symbol-description\n const elevationId = Symbol();\n\n // Validate that the added permissions are valid UUIDs\n Object.values(addedPermissions).forEach((entityIds) => {\n Object.keys(entityIds).forEach((entityId) => {\n if (!validateUUID(entityId)) {\n throw new Error(`Entity id on elevatePermissions is not a valid UUID, provided: ${entityId}`);\n }\n });\n });\n\n const currentUserTrace = getCurrentContext();\n if (!currentUserTrace) {\n throw new Error('Cannot find current user cross services trace');\n }\n\n const currentElevation = JSON.parse(currentUserTrace.context[ELEVATED_PERMISSIONS_HEADER] || '{}');\n const newElevation = Object.assign(currentElevation, addedPermissions);\n this.privateElevatedPermissionsHash.set(elevationId, newElevation);\n currentUserTrace.context.set(ELEVATED_PERMISSIONS_HEADER, JSON.stringify(this.elevatedPermissions));\n const cleanup = () => {\n this.privateElevatedPermissionsHash.delete(elevationId);\n currentUserTrace.context.set(ELEVATED_PERMISSIONS_HEADER, JSON.stringify(this.elevatedPermissions));\n };\n cleanup[Symbol.dispose] = cleanup;\n return cleanup;\n }\n\n public async getUserPermissionsLegacy() {\n if (!this.id) {\n return undefined;\n }\n if (this.privatePermissionsLegacy) {\n return this.privatePermissionsLegacy;\n }\n\n const cacheKey = objectHash({\n id: this.id,\n contextIds: this.contextIds,\n legacy: true,\n });\n let data = userCache.get(cacheKey);\n\n if (!data) {\n ({ data } = await IdentityNetwork.get(`/api/v1/users/${this.id}/authorization-payload-legacy`, { params: { contextIds: this.contextIds } }));\n userCache.set(cacheKey, data);\n }\n\n this.privatePermissionsLegacy = data;\n return this.privatePermissionsLegacy;\n }\n\n public get permissionsLegacy(): any {\n if (!this.privatePermissionsLegacy) {\n throw new Error('Cannot get permissionsLegacy without calling (async) getUserPermissionsLegacy before');\n }\n return this.privatePermissionsLegacy;\n }\n\n public async getUserAppPermissions(appId: string, clientSecret: string): Promise<UserPayload | undefined> {\n if (!this.id || !appId || !clientSecret) {\n return undefined;\n }\n const currentAppPermission = this.appPermission[appId];\n\n if (currentAppPermission) {\n return currentAppPermission;\n }\n\n const cacheKey = `${this.id}:${appId}`;\n\n const cachedResult = userCache.get<UserPayload>(cacheKey);\n if (cachedResult) {\n this.appPermission[appId] = cachedResult;\n return cachedResult;\n }\n\n const { data } = await AutofleetApiNetwork.post<UserPayload>(`/api/v1/apps/${appId}/get-user-payload`, {\n userId: this.id,\n }, {\n headers: {\n 'x-autofleet-apps-secret': clientSecret,\n },\n });\n\n userCache.set(cacheKey, data);\n this.appPermission[appId] = data;\n return this.appPermission[appId];\n }\n}\n","import { AutofleetApiNetwork } from './services';\n\nexport const decodeAppBearer = async (bearer: string, appId: string): Promise<any> => {\n const { data: decoded } = await AutofleetApiNetwork.post('/api/v1/auth', { bearer, appId });\n return decoded;\n};\n\nexport const getClientSecret = async (appId: string): Promise<any> => {\n const { data: secret } = await AutofleetApiNetwork.get(`/api/v1/auth/client-secret/${appId}`);\n return secret;\n};\n","export default class AppDoesNotExist extends Error {\n name = 'AppDoesNotExist';\n\n message = 'app does not exist';\n}\n","export const IDENTITY_MS = 'identity-ms';\nexport const ACCESS_TOKEN = 'accessToken';\nexport const USER_OBJECT = 'userObject';\nexport const USER_TRACING_HEADER = 'x-af-user-id';\nexport const ORIGIN_HEADER = 'X-IAF-ORIGIN-SERVICE';\nexport const USER_PERMISSIONS_HEADER = 'x-af-user-permissions';\nexport const LOWER_CASE_ORIGIN_HEADER = ORIGIN_HEADER.toLowerCase();\nexport const AUTOFLEET_APPS_SECRET_HEADER = 'x-autofleet-apps-secret';\n","import type { IncomingHttpHeaders } from 'node:http';\nimport { getCurrentContext } from '@autofleet/outbreak';\nimport ApiUser, { CONTEXTS_IDS_HEADER, ELEVATED_PERMISSIONS_HEADER, type UserPayload } from './ApiUser';\nimport {\n IDENTITY_MS,\n USER_OBJECT,\n USER_TRACING_HEADER,\n ORIGIN_HEADER,\n LOWER_CASE_ORIGIN_HEADER,\n} from './const';\n\nexport type CustomPermissionLoader = (userId: string) => Promise<UserPayload>;\nexport interface AuthFromUserIdHeaderOptions {\n eagerLoadUserPermissions?: boolean;\n eagerLoadUserPermissionsLegacy?: boolean;\n customPermissionLoader?: CustomPermissionLoader;\n}\n\nexport const authFromUserIdHeader = async (options: AuthFromUserIdHeaderOptions, headers: IncomingHttpHeaders): Promise<ApiUser | undefined> => {\n const originHeader = headers[ORIGIN_HEADER] || headers[LOWER_CASE_ORIGIN_HEADER] || '';\n if (!Array.isArray(originHeader) && originHeader.toLowerCase() === IDENTITY_MS) {\n return undefined;\n }\n const {\n eagerLoadUserPermissions,\n eagerLoadUserPermissionsLegacy,\n customPermissionLoader,\n } = options;\n const userId = headers[USER_TRACING_HEADER] as string;\n if (!userId || Array.isArray(userId)) {\n return undefined;\n }\n\n const elevatedPermissionsFromHeader = headers[ELEVATED_PERMISSIONS_HEADER]?.length > 0 ? JSON.parse(headers[ELEVATED_PERMISSIONS_HEADER] as string) : {};\n const contextIds = (headers?.[CONTEXTS_IDS_HEADER] as string)?.split(',');\n\n const userObject = new ApiUser(userId, 'user', elevatedPermissionsFromHeader, contextIds);\n if (eagerLoadUserPermissions) {\n if (customPermissionLoader) {\n await userObject.useCustomPermissionLoader(customPermissionLoader);\n } else {\n await userObject.getUserPermissions();\n }\n }\n\n if (eagerLoadUserPermissionsLegacy) {\n await userObject.getUserPermissionsLegacy();\n }\n\n getCurrentContext().nonHeaderContext?.set(USER_OBJECT, userObject);\n return userObject;\n};\n","import type { Handler, Request } from 'express';\nimport { getCurrentContext, newTrace, traceTypes } from '@autofleet/outbreak';\nimport jwt from 'jsonwebtoken';\nimport ApiUser, { CONTEXTS_IDS_HEADER } from './ApiUser';\nimport { decodeAppBearer } from '../app-auth';\nimport AppDoesNotExist from '../exceptions/appDoesNotExist';\nimport { decodeBearer, getAuthFromBearer } from '../utils';\nimport {\n ACCESS_TOKEN,\n USER_OBJECT,\n USER_TRACING_HEADER,\n USER_PERMISSIONS_HEADER,\n AUTOFLEET_APPS_SECRET_HEADER,\n} from './const';\nimport { authFromUserIdHeader, AuthFromUserIdHeaderOptions } from './common';\n\ndeclare module 'express-serve-static-core' {\n // eslint-disable-next-line @typescript-eslint/no-shadow\n interface Request {\n user: ApiUser;\n }\n}\n\nexport const middleware = (options: AuthFromUserIdHeaderOptions = {}): Handler => async (req, res, next): Promise<any> => {\n try {\n const userObject = await authFromUserIdHeader(options, req.headers);\n if (userObject) {\n req.user = userObject;\n // Added in order to support outbreak.\n // @ts-expect-error we are setting an object onto the request headers.\n req.headers[USER_PERMISSIONS_HEADER] = userObject;\n }\n\n next();\n } catch (e) {\n res.status(401).json({ error: 'cannot authenticate user' });\n }\n};\n\nexport const middlewareWithDecode = (options: {\n eagerLoadUserPermissions?: boolean;\n eagerLoadUserPermissionsLegacy?: boolean;\n returnErrorIfNoToken?: boolean\n} = {}): Handler => async (req, res, next): Promise<void> => {\n const {\n eagerLoadUserPermissions,\n eagerLoadUserPermissionsLegacy,\n returnErrorIfNoToken,\n } = options;\n let decoded;\n if (req.headers.authorization) {\n try {\n decoded = await decodeBearer(req.headers.authorization);\n } catch (e) {\n if (e instanceof jwt.TokenExpiredError) {\n res.status(401).json({ errors: ['Access token expired'] });\n } else if (e instanceof jwt.JsonWebTokenError) {\n res.status(400).json({ errors: [e.message] });\n } else {\n res.status(500).json({ errors: ['Server error while parsing token'] });\n }\n return;\n }\n const userId = decoded?.user?.id;\n\n if (userId) {\n req.headers[USER_TRACING_HEADER] = userId;\n }\n\n const contextIds = (req.headers?.[CONTEXTS_IDS_HEADER] as string)?.split(',');\n const userObject = new ApiUser(userId, decoded?.user?.accountType, undefined, contextIds);\n\n if (eagerLoadUserPermissions || eagerLoadUserPermissionsLegacy) {\n await Promise.all([\n eagerLoadUserPermissions && userObject.getUserPermissions(),\n eagerLoadUserPermissionsLegacy && userObject.getUserPermissionsLegacy(),\n ]);\n }\n\n req.user = userObject;\n getCurrentContext().nonHeaderContext?.set(USER_OBJECT, userObject);\n\n // Added in order to support outbreak.\n // @ts-expect-error we are setting an object onto the request headers.\n req.headers[USER_PERMISSIONS_HEADER] = userObject;\n } else if (returnErrorIfNoToken) {\n res.status(401).json({ errors: ['No token provided'] });\n return;\n }\n next();\n};\n\nexport const appMiddleware = (options: {\n appId: string,\n clientSecret: string\n}): Handler => async (req, res, next): Promise<void> => {\n const {\n appId,\n clientSecret,\n } = options;\n let decoded;\n\n if (!req.headers.authorization) {\n res.status(401).json({ errors: ['No token provided'] });\n return;\n }\n\n try {\n decoded = await decodeAppBearer(req.headers.authorization, appId);\n if (!decoded) {\n throw new AppDoesNotExist();\n }\n } catch (e) {\n if (e instanceof jwt.TokenExpiredError) {\n res.status(401).json({ errors: ['Access token expired'] });\n return;\n }\n if ([jwt.JsonWebTokenError, AppDoesNotExist].some((Err) => e instanceof Err)) {\n res.status(400).json({ errors: [e.message] });\n return;\n }\n res.status(500).json({ errors: ['Server error while parsing token'] });\n return;\n }\n const userId = decoded?.userId;\n if (userId) {\n req.headers[USER_TRACING_HEADER] = userId;\n }\n\n const userObject = new ApiUser(userId);\n\n if (appId) {\n req.headers[AUTOFLEET_APPS_SECRET_HEADER] = clientSecret;\n // Won't work until we find a better solution for identity ms\n await userObject.getUserAppPermissions(appId, clientSecret);\n }\n\n req.user = userObject;\n const currentTraceContext = getCurrentContext().nonHeaderContext;\n currentTraceContext?.set(USER_OBJECT, userObject);\n currentTraceContext?.set(ACCESS_TOKEN, getAuthFromBearer(req.headers.authorization));\n\n // Added in order to support outbreak.\n // @ts-expect-error we are setting an object onto the request headers.\n req.headers[USER_PERMISSIONS_HEADER] = userObject;\n\n next();\n};\n\nexport const eagerLoadPermissionsMiddleware: Handler = async (req, res, next) => {\n await req.user.getUserPermissions();\n next();\n};\n\nexport const getDecodedBearer = (req: Request) => {\n if (!req.headers.authorization) {\n return null;\n }\n return decodeBearer(req.headers.authorization);\n};\n\nexport const createOrSetRabbitTrace = async (trace: ReturnType<typeof newTrace> | undefined, userId: string | undefined) => {\n const userObject = new ApiUser(userId);\n\n await userObject.getUserPermissions();\n // eslint-disable-next-line no-param-reassign\n trace ??= newTrace(traceTypes.RABBIT);\n trace.nonHeaderContext.set(USER_OBJECT, userObject);\n};\n\nexport default ApiUser;\n","import type { FastifyPluginCallback } from 'fastify';\nimport type ApiUser from './ApiUser';\nimport { AuthFromUserIdHeaderOptions, authFromUserIdHeader } from './common';\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n user?: ApiUser;\n }\n}\n\n// eslint-disable-next-line import/prefer-default-export\nexport const authFromUserIdHeaderPlugin: FastifyPluginCallback<AuthFromUserIdHeaderOptions> = (fastify, options, done) => {\n fastify.decorateRequest('user', undefined);\n fastify.addHook('onRequest', async (request, reply) => {\n try {\n const user = await authFromUserIdHeader(options, request.headers);\n if (user) {\n request.user = user;\n }\n } catch (e) {\n reply.status(401).send({ error: 'cannot authenticate user' });\n }\n });\n\n done();\n};\nauthFromUserIdHeaderPlugin[Symbol.for('skip-override')] = true; // Prevent Fastify from overriding the plugin\n","import { getCurrentContext } from '@autofleet/outbreak';\nimport { USER_OBJECT } from './user/const';\nimport ApiUser, { type UserPayload } from './user/ApiUser';\n\nexport const getUser = () : ApiUser | undefined => getCurrentContext().nonHeaderContext?.get(USER_OBJECT) as ApiUser | undefined;\n\nexport const isUserExist = () => getUser()?.id;\n\nconst checkUserPermissions = (\n entityId: string,\n entityType: Exclude<keyof UserPayload, 'accountType' | 'createdAt'>,\n) => !isUserExist() || Object.hasOwn(getUser()!.permissions[entityType], entityId);\n\nexport const checkFleetPermission = (fleetId: string) => checkUserPermissions(fleetId, 'fleets');\nexport const checkBusinessModelPermission = (businessModelId: string) => checkUserPermissions(businessModelId, 'businessModels');\nexport const checkDemandSourcePermission = (demandSourceId: string) => checkUserPermissions(demandSourceId, 'demandSources');\n","import type ApiUser from './user';\n\n// eslint-disable-next-line import/prefer-default-export\nexport class UnauthorizedAccessError extends Error {\n constructor(public user: ApiUser | null = null, message = 'UnauthorizedAccessError') {\n super(message);\n this.name = 'UnauthorizedAccessError';\n }\n}\n","import jwt from 'jsonwebtoken';\n\nexport const AUTHORIZATION_METHODS = {\n NONE: 'NONE',\n BASIC: 'BASIC',\n JWT: 'JWT',\n};\n\nconst AUTHORIZATION_ACTIONS = {\n [AUTHORIZATION_METHODS.NONE]: () => undefined,\n [AUTHORIZATION_METHODS.BASIC]: (authorizationSettings: any) => {\n const { username, password } = authorizationSettings;\n const encodedCredentials = Buffer.from(`${username}:${password}`).toString('base64');\n return `Basic ${encodedCredentials}`;\n },\n [AUTHORIZATION_METHODS.JWT]: (authorizationSettings: any) => {\n const { secret } = authorizationSettings;\n if (secret) {\n return `Bearer ${jwt.sign({}, secret, { expiresIn: 10 })}`;\n }\n return undefined;\n },\n};\n\nexport const getAuthorizationHeader = (authorizationSettings: { method: string } | undefined): string | undefined => {\n const authorizationMethod = authorizationSettings?.method;\n\n if (!authorizationMethod || !AUTHORIZATION_ACTIONS[authorizationMethod]) {\n return undefined;\n }\n\n return AUTHORIZATION_ACTIONS[authorizationMethod](authorizationSettings);\n};\n","import type { LoggerInstanceManager } from '@autofleet/logger';\nimport * as outbreak from '@autofleet/outbreak';\nimport User, {\n middleware,\n eagerLoadPermissionsMiddleware,\n middlewareWithDecode,\n getDecodedBearer,\n appMiddleware,\n createOrSetRabbitTrace,\n} from './user';\nimport { authFromUserIdHeaderPlugin } from './user/fastify';\nimport { type UserPayload, CONTEXTS_IDS_HEADER } from './user/ApiUser';\nimport {\n checkFleetPermission,\n checkBusinessModelPermission,\n checkDemandSourcePermission,\n isUserExist,\n getUser,\n} from './check-permission';\nimport { UnauthorizedAccessError } from './errors';\nimport { getRefreshTokenSecret, getTokenSecret } from './secret-getter';\nimport { AUTHORIZATION_METHODS, getAuthorizationHeader } from './authorization';\n\nconst getCurrentPayload = outbreak.getCurrentContext;\n\ntype OutbreakOptions = Parameters<typeof outbreak.default>[0];\ntype LoggerWithContextMiddleware = Partial<Pick<LoggerInstanceManager, 'addContextMiddleware'>>;\nconst enableTracing = ({ outbreakOptions = {}, logger }: { outbreakOptions?: OutbreakOptions, logger?: LoggerWithContextMiddleware } = {}): void => {\n outbreak.default({\n headersPrefix: 'x-af',\n contextMiddlewareGetter: logger?.addContextMiddleware,\n ...outbreakOptions,\n });\n};\n\nconst { traceTypes, newTrace } = outbreak;\n\nexport {\n traceTypes,\n newTrace,\n enableTracing,\n User,\n middleware,\n middlewareWithDecode,\n eagerLoadPermissionsMiddleware,\n getCurrentPayload,\n getDecodedBearer,\n checkFleetPermission,\n checkBusinessModelPermission,\n checkDemandSourcePermission,\n isUserExist,\n getUser,\n getRefreshTokenSecret,\n getTokenSecret,\n UnauthorizedAccessError,\n appMiddleware,\n createOrSetRabbitTrace,\n outbreak,\n AUTHORIZATION_METHODS,\n getAuthorizationHeader,\n type UserPayload,\n CONTEXTS_IDS_HEADER,\n authFromUserIdHeaderPlugin,\n};\n\nexport default {\n traceTypes,\n newTrace,\n User,\n middleware,\n middlewareWithDecode,\n eagerLoadPermissionsMiddleware,\n getCurrentPayload,\n getDecodedBearer,\n checkFleetPermission,\n checkBusinessModelPermission,\n checkDemandSourcePermission,\n isUserExist,\n getUser,\n UnauthorizedAccessError,\n appMiddleware,\n createOrSetRabbitTrace,\n outbreak,\n AUTHORIZATION_METHODS,\n getAuthorizationHeader,\n CONTEXTS_IDS_HEADER,\n authFromUserIdHeaderPlugin,\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/secret-getter.ts","../src/utils.ts","../src/services.ts","../src/user/ApiUser.ts","../src/app-auth.ts","../src/exceptions/appDoesNotExist.ts","../src/user/const.ts","../src/user/common.ts","../src/user/index.ts","../src/user/fastify.ts","../src/check-permission.ts","../src/errors.ts","../src/authorization.ts","../src/permissions/index.ts","../src/permissions/SDK/permissionCache.ts","../src/permissions/SDK/consts.ts","../src/permissions/SDK/evaluatePermissions.ts","../src/permissions/middleware/requirePermissions.ts","../src/index.ts"],"names":["DEPRECATED_JWT_SECRET","JWT_NEW_SECRET","DEPRECATED_REFRESH_JWT_SECRET","REFRESH_JWT_SECRET","DEPRECATION_UNIX_TIMESTAMP","getRelevantSecret","token","deprecatedSecret","newSecret","deprecationTime","moment","unixTime","iat","jwt","getRefreshTokenSecret","getTokenSecret","getAuthFromBearer","bearer","decodeBearer","appSecret","EMPTY_UUID","FULL_UUID","VALID_CHARS_REGEX","UUID_VERSION_REGEX","UUID_REGEX","validateUUID","uuid","CACHE_LIFETIME_IN_SEC","apiGwUrl","IdentityNetwork","Network","AutofleetApiNetwork","ELEVATED_PERMISSIONS_HEADER","CONTEXTS_IDS_HEADER","userCache","NodeCache","mergePermissions","target","sources","permissions","source","entityType","entityId","perms","ApiUser","id","accountType","elevatedPermissions","contextIds","cacheKey","objectHash","data","customPermissionLoader","cachedResult","key","addedPermissions","elevationId","entityIds","currentUserTrace","getCurrentContext","currentElevation","newElevation","cleanup","appId","clientSecret","currentAppPermission","decodeAppBearer","decoded","AppDoesNotExist","IDENTITY_MS","ACCESS_TOKEN","USER_OBJECT","USER_TRACING_HEADER","ORIGIN_HEADER","USER_PERMISSIONS_HEADER","LOWER_CASE_ORIGIN_HEADER","AUTOFLEET_APPS_SECRET_HEADER","authFromUserIdHeader","options","headers","originHeader","eagerLoadUserPermissions","eagerLoadUserPermissionsLegacy","userId","elevatedPermissionsFromHeader","userObject","middleware","req","res","next","middlewareWithDecode","returnErrorIfNoToken","e","appMiddleware","Err","currentTraceContext","eagerLoadPermissionsMiddleware","getDecodedBearer","createOrSetRabbitTrace","trace","newTrace","traceTypes","user_default","authFromUserIdHeaderPlugin","fastify","done","request","reply","user","getUser","isUserExist","checkUserPermissions","checkFleetPermission","fleetId","checkBusinessModelPermission","businessModelId","checkDemandSourcePermission","demandSourceId","UnauthorizedAccessError","message","AUTHORIZATION_METHODS","AUTHORIZATION_ACTIONS","authorizationSettings","username","password","secret","getAuthorizationHeader","authorizationMethod","permissions_exports","__export","permissions_default","middlewares","sdk","PermissionCache","cache","contextId","PermissionsByContextId","ttl","cacheEntries","requiredPermissions","sortedPermissions","seenKey","permissionCache","PERMISSIONS_EVALUATION_OPERATORS","PERMISSION_ERROR_TYPES","PERMISSION_ERROR_MESSAGES","evaluatePermissionsByOperator","operator","permissionsSet","matchingPermissions","permission","checkAuthorizeRequirements","permissionsEvaluationByContextId","requireAll","permissionsEvaluationValues","evaluation","validateInput","errors","createErrorResult","error","cachePermissionsResults","resolvedPermissions","permissionsToCache","contextIdsWithoutPermissions","getUnseenContextIds","seenPermissions","createSeenContextEntries","uncachedContextIds","unseenContextIds","seenContextIds","seenEntries","processCachedPermissions","cachedPermissions","processedPermissions","hasRequiredPermissions","callIdentityAPI","response","reEvaluatedPermissions","validateEvaluationInput","logger","validationErrors","resolveAllPermissions","resolvedPermissionsFromCache","seenContextEntries","resolvedPermissionsFromIdentityMS","evaluatePermissions","permissionsEvaluationOperator","timeout","resolvedUserId","validationError","isAuthorized","getContextIds","contextIdsFromHeader","contextIdsFromQuery","contextIdsFromBody","handleError","errorLabel","code","enforce","additionalInfo","requirePermissions","handleErrorWrapper","result","getCurrentPayload","I","enableTracing","outbreakOptions","outbreak","index_default"],"mappings":"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","file":"index.cjs","sourcesContent":["import jwt from 'jsonwebtoken';\nimport moment from 'moment';\n\nconst {\n DEPRECATED_JWT_SECRET, JWT_NEW_SECRET,\n DEPRECATED_REFRESH_JWT_SECRET, REFRESH_JWT_SECRET,\n DEPRECATION_UNIX_TIMESTAMP,\n} = process.env;\n\nconst getRelevantSecret = (token: string | undefined, deprecatedSecret: string, newSecret: string): string => {\n const deprecationTime = moment(parseInt(DEPRECATION_UNIX_TIMESTAMP, 10) * 1000);\n try {\n let unixTime: moment.Moment;\n if (token) {\n const { iat } = jwt.decode(token) as jwt.JwtPayload;\n unixTime = moment(iat * 1000);\n } else {\n unixTime = moment();\n }\n return unixTime.isBefore(deprecationTime) ? deprecatedSecret : newSecret;\n } catch (e) {\n return newSecret;\n }\n};\n\nexport const getRefreshTokenSecret = (token?: string): string => getRelevantSecret(token, DEPRECATED_REFRESH_JWT_SECRET, REFRESH_JWT_SECRET);\nexport const getTokenSecret = (token?: string): string => getRelevantSecret(token, DEPRECATED_JWT_SECRET, JWT_NEW_SECRET);\n","import type { UUID } from 'node:crypto';\nimport jwt from 'jsonwebtoken';\nimport { getTokenSecret } from './secret-getter';\n\ntype Context = Partial<Record<ContextProp | 'id', string>> & { subSystem?: SubSystemType; permissions?: string[]; entityId: string; };\n\nconst CONTEXT_PROPS = ['fleetId', 'businessModelId', 'demandSourceId'] as const;\ntype ContextProp = typeof CONTEXT_PROPS[number];\nconst CONTEXT_MAP_PROPS = {\n fleet: 'fleets',\n business: 'businessModels',\n demand: 'demandSources',\n} as const;\ntype SubSystemType = keyof typeof CONTEXT_MAP_PROPS;\ntype ContextSubSystemProp = typeof CONTEXT_MAP_PROPS[SubSystemType];\n\nexport const getAuthFromBearer = (bearer: string): string => bearer.replace('Bearer ', '');\n\nexport const decodeBearer = (bearer: string, appSecret?: string): any => {\n const token = getAuthFromBearer(bearer);\n const decoded = jwt.verify(token, appSecret || getTokenSecret(token));\n return decoded;\n};\n\nexport const parsePermissions = (contextId: string, decodedToken: { contexts: Context[]; }): { key: string; value: string; } | undefined => {\n if (!decodedToken) return undefined;\n const { contexts } = decodedToken;\n const activeContext = contexts.find((context) => context.id === contextId);\n\n const permissionsValue = `${activeContext.permissions?.map((cp) => `${cp},`)}`;\n\n return {\n key: activeContext.entityId,\n value: permissionsValue,\n };\n};\n\ntype EntitiesFromContext = { [key in ContextSubSystemProp]?: Record<string, string> };\nexport const getEntitiesFromContext = (contextId: string | undefined, decodedToken: { contexts: Context[]; }): EntitiesFromContext => {\n if (!decodedToken) return {};\n let { contexts } = decodedToken;\n if (contextId) {\n contexts = contexts.filter((context) => context.id === contextId);\n }\n\n const attributes: EntitiesFromContext = {};\n contexts.forEach((context) => {\n const prop = CONTEXT_MAP_PROPS[context.subSystem || 'business'];\n\n const permissions = parsePermissions(context.id, decodedToken);\n if (!permissions) return;\n attributes[prop] ||= {};\n attributes[prop][permissions.key] = permissions.value;\n });\n\n return attributes;\n};\n\ntype ContextAttributes = { [key in ContextProp]?: string[] };\nexport const getContextAttributes = (contextId: string | undefined, decodedToken: { contexts: Context[]; }): ContextAttributes => {\n if (!decodedToken) return {};\n let { contexts } = decodedToken;\n if (contextId) {\n contexts = contexts.filter((context) => context.id === contextId);\n }\n const attributes: ContextAttributes = {};\n contexts.forEach((context) => {\n CONTEXT_PROPS.forEach((prop) => {\n if (context[prop]) {\n attributes[prop] ||= [];\n attributes[prop].push(context[prop]);\n }\n });\n });\n return attributes;\n};\n\nconst EMPTY_UUID = '00000000-0000-0000-0000-000000000000';\nconst FULL_UUID = 'ffffffff-ffff-ffff-ffff-ffffffffffff';\nconst VALID_CHARS_REGEX = '[0-9a-f]';\nconst UUID_VERSION_REGEX = '[1-8]';\nconst UUID_REGEX = new RegExp(\n `^(?:${VALID_CHARS_REGEX}{8}-${VALID_CHARS_REGEX}{4}-${UUID_VERSION_REGEX}${VALID_CHARS_REGEX}{3}-[89ab]${VALID_CHARS_REGEX}{3}-${VALID_CHARS_REGEX}{12}|${EMPTY_UUID}|${FULL_UUID})$`,\n 'i',\n);\nexport function validateUUID(uuid: unknown): uuid is UUID {\n return typeof uuid === 'string' && UUID_REGEX.test(uuid);\n}\n","import Network from '@autofleet/network';\n\nconst CACHE_LIFETIME_IN_SEC = 10;\nconst apiGwUrl = process.env.API_GATEWAY_URL || 'https://api.autofleet.io';\n\n// eslint-disable-next-line import/prefer-default-export\nexport const IdentityNetwork = new Network({\n serviceName: 'IDENTITY_MS',\n retries: 3,\n retryCondition: () => true,\n cache: process.env.NODE_ENV !== 'test' ? {\n maxAge: CACHE_LIFETIME_IN_SEC * 1000,\n } : undefined,\n});\n\nexport const AutofleetApiNetwork = new Network({\n baseURL: apiGwUrl,\n serviceUrl: apiGwUrl,\n retries: 3,\n retryCondition: () => true,\n cache: process.env.NODE_ENV !== 'test' ? {\n maxAge: CACHE_LIFETIME_IN_SEC * 1000,\n } : undefined,\n});\n","import NodeCache from 'node-cache';\nimport objectHash from 'object-hash';\nimport { getCurrentContext } from '@autofleet/outbreak';\nimport { validateUUID } from '../utils';\nimport { AutofleetApiNetwork, IdentityNetwork } from '../services';\n\nexport type AccountType = 'client' | 'user' | 'service' | 'driver'\ninterface EntityPermissions {\n [key: string]: string[];\n}\n\nexport const ELEVATED_PERMISSIONS_HEADER = 'x-af-elevated-permissions';\nexport const CONTEXTS_IDS_HEADER = 'x-af-context-ids';\n\nexport interface UserPayload {\n businessModels: EntityPermissions;\n fleets: EntityPermissions;\n demandSources: EntityPermissions;\n businessAccounts?: EntityPermissions;\n accountType?: AccountType;\n contexts?: EntityPermissions;\n createdAt?: string;\n}\n\nexport interface PartialUserPayload {\n businessModels?: EntityPermissions;\n fleets?: EntityPermissions;\n demandSources?: EntityPermissions;\n vehicles?: EntityPermissions;\n drivers?: EntityPermissions;\n businessAccounts?: EntityPermissions;\n}\n\nconst userCache = new NodeCache({ stdTTL: 10 });\n\nconst mergePermissions = (target: UserPayload, sources: Iterable<PartialUserPayload>): UserPayload => {\n const permissions: UserPayload = {\n ...target,\n fleets: { ...target?.fleets },\n businessModels: { ...target?.businessModels },\n demandSources: { ...target?.demandSources },\n // Clone other nested objects as needed\n };\n\n // eslint-disable-next-line no-restricted-syntax\n for (const source of sources) {\n Object.keys(source).forEach((entityType) => {\n // eslint-disable-next-line no-param-reassign\n permissions[entityType] ??= {};\n Object.entries(source[entityType]!).forEach(([entityId, perms]) => {\n // eslint-disable-next-line no-param-reassign\n permissions[entityType][entityId] = (permissions[entityType][entityId] || []).concat(perms);\n });\n });\n }\n\n return permissions;\n};\n\nif (typeof Symbol.dispose !== 'symbol') {\n // Polyfill for dispose if it does not exist, based on https://github.com/nodejs/node/blob/9a9409ff1f45c968173118de4cd37dea784f8ec9/lib/internal/process/pre_execution.js#L163-L171\n Object.defineProperty(Symbol, 'dispose', {\n // @ts-expect-error: TypeScript does not recognize __proto__ as a valid property\n __proto__: null,\n configurable: false,\n enumerable: false,\n value: Symbol.for('nodejs.dispose'),\n writable: false,\n });\n}\nif (typeof Symbol.asyncDispose !== 'symbol') {\n // Polyfill for asyncDispose if it does not exist, based on https://github.com/nodejs/node/blob/9a9409ff1f45c968173118de4cd37dea784f8ec9/lib/internal/process/pre_execution.js#L174-L183\n Object.defineProperty(Symbol, 'asyncDispose', {\n // @ts-expect-error: TypeScript does not recognize __proto__ as a valid property\n __proto__: null,\n configurable: false,\n enumerable: false,\n value: Symbol.for('nodejs.asyncDispose'),\n writable: false,\n });\n}\n\nexport default class ApiUser {\n private privatePermissions: UserPayload | undefined;\n\n private readonly privateElevatedPermissionsHash = new Map<symbol, PartialUserPayload | undefined>();\n\n private privatePermissionsLegacy: any;\n\n private readonly appPermission: {[key: string]: any; } = {};\n\n public readonly emptyUser: boolean;\n\n constructor(public id? : string, public accountType?: AccountType, elevatedPermissions?: PartialUserPayload, public contextIds?: string[]) {\n this.emptyUser = !!id;\n if (elevatedPermissions) {\n this.privateElevatedPermissionsHash.set(Symbol('initial'), elevatedPermissions);\n }\n }\n\n public async getUserPermissions(): Promise<UserPayload> {\n if (!this.id) {\n return undefined;\n }\n if (this.privatePermissions) {\n return this.privatePermissions;\n }\n const cacheKey = objectHash({\n id: this.id,\n contextIds: this.contextIds,\n });\n\n let data = userCache.get<UserPayload>(cacheKey);\n\n if (!data) {\n ({ data } = await IdentityNetwork.get<UserPayload>(`/api/v1/users/${this.id}/authorization-payload`, { params: { contextIds: this.contextIds } }));\n userCache.set(cacheKey, data);\n }\n\n this.accountType = data.accountType;\n this.privatePermissions = data;\n return this.privatePermissions;\n }\n\n public async useCustomPermissionLoader(customPermissionLoader: (userId: string) => UserPayload | PromiseLike<UserPayload>): Promise<UserPayload> {\n if (!this.id) {\n return undefined;\n }\n if (this.privatePermissions) {\n return this.privatePermissions;\n }\n\n const cacheKey = this.id;\n\n const cachedResult = userCache.get<UserPayload>(cacheKey);\n if (cachedResult) {\n this.privatePermissions = cachedResult;\n return cachedResult;\n }\n\n const data = await customPermissionLoader(this.id);\n userCache.set(cacheKey, data);\n\n this.privatePermissions = data;\n return this.privatePermissions;\n }\n\n public get businessModels(): string[] {\n return this.getUserProperty('businessModels');\n }\n\n public get fleets(): string[] {\n return this.getUserProperty('fleets');\n }\n\n public get demandSources(): string[] {\n return this.getUserProperty('demandSources');\n }\n\n private getUserProperty(key: keyof UserPayload): string[] {\n if (!this.privatePermissions) {\n throw new Error(`Cannot get ${key} without calling (async) getUserPermissions before`);\n }\n return Object.keys(this.privatePermissions[key] || {});\n }\n\n public get elevatedPermissions(): UserPayload {\n return mergePermissions(undefined, this.privateElevatedPermissionsHash.values());\n }\n\n public get permissions(): UserPayload | undefined {\n if (!this.privatePermissions) {\n throw new Error('Cannot get permissions without calling (async) getUserPermissions before');\n }\n\n return mergePermissions(this.privatePermissions, this.privateElevatedPermissionsHash.values());\n }\n\n public elevatePermissions(addedPermissions: PartialUserPayload): (() => void) & { [Symbol.dispose]: () => void } {\n // @itayankri is concerned about memory consumption, so create a symbol with no description, to avoid assigning memory for the description string\n // eslint-disable-next-line symbol-description\n const elevationId = Symbol();\n\n // Validate that the added permissions are valid UUIDs\n Object.values(addedPermissions).forEach((entityIds) => {\n Object.keys(entityIds).forEach((entityId) => {\n if (!validateUUID(entityId)) {\n throw new Error(`Entity id on elevatePermissions is not a valid UUID, provided: ${entityId}`);\n }\n });\n });\n\n const currentUserTrace = getCurrentContext();\n if (!currentUserTrace) {\n throw new Error('Cannot find current user cross services trace');\n }\n\n const currentElevation = JSON.parse(currentUserTrace.context[ELEVATED_PERMISSIONS_HEADER] || '{}');\n const newElevation = Object.assign(currentElevation, addedPermissions);\n this.privateElevatedPermissionsHash.set(elevationId, newElevation);\n currentUserTrace.context.set(ELEVATED_PERMISSIONS_HEADER, JSON.stringify(this.elevatedPermissions));\n const cleanup = () => {\n this.privateElevatedPermissionsHash.delete(elevationId);\n currentUserTrace.context.set(ELEVATED_PERMISSIONS_HEADER, JSON.stringify(this.elevatedPermissions));\n };\n cleanup[Symbol.dispose] = cleanup;\n return cleanup;\n }\n\n public async getUserPermissionsLegacy() {\n if (!this.id) {\n return undefined;\n }\n if (this.privatePermissionsLegacy) {\n return this.privatePermissionsLegacy;\n }\n\n const cacheKey = objectHash({\n id: this.id,\n contextIds: this.contextIds,\n legacy: true,\n });\n let data = userCache.get(cacheKey);\n\n if (!data) {\n ({ data } = await IdentityNetwork.get(`/api/v1/users/${this.id}/authorization-payload-legacy`, { params: { contextIds: this.contextIds } }));\n userCache.set(cacheKey, data);\n }\n\n this.privatePermissionsLegacy = data;\n return this.privatePermissionsLegacy;\n }\n\n public get permissionsLegacy(): any {\n if (!this.privatePermissionsLegacy) {\n throw new Error('Cannot get permissionsLegacy without calling (async) getUserPermissionsLegacy before');\n }\n return this.privatePermissionsLegacy;\n }\n\n public async getUserAppPermissions(appId: string, clientSecret: string): Promise<UserPayload | undefined> {\n if (!this.id || !appId || !clientSecret) {\n return undefined;\n }\n const currentAppPermission = this.appPermission[appId];\n\n if (currentAppPermission) {\n return currentAppPermission;\n }\n\n const cacheKey = `${this.id}:${appId}`;\n\n const cachedResult = userCache.get<UserPayload>(cacheKey);\n if (cachedResult) {\n this.appPermission[appId] = cachedResult;\n return cachedResult;\n }\n\n const { data } = await AutofleetApiNetwork.post<UserPayload>(`/api/v1/apps/${appId}/get-user-payload`, {\n userId: this.id,\n }, {\n headers: {\n 'x-autofleet-apps-secret': clientSecret,\n },\n });\n\n userCache.set(cacheKey, data);\n this.appPermission[appId] = data;\n return this.appPermission[appId];\n }\n}\n","import { AutofleetApiNetwork } from './services';\n\nexport const decodeAppBearer = async (bearer: string, appId: string): Promise<any> => {\n const { data: decoded } = await AutofleetApiNetwork.post('/api/v1/auth', { bearer, appId });\n return decoded;\n};\n\nexport const getClientSecret = async (appId: string): Promise<any> => {\n const { data: secret } = await AutofleetApiNetwork.get(`/api/v1/auth/client-secret/${appId}`);\n return secret;\n};\n","export default class AppDoesNotExist extends Error {\n name = 'AppDoesNotExist';\n\n message = 'app does not exist';\n}\n","export const IDENTITY_MS = 'identity-ms';\nexport const ACCESS_TOKEN = 'accessToken';\nexport const USER_OBJECT = 'userObject';\nexport const USER_TRACING_HEADER = 'x-af-user-id';\nexport const ORIGIN_HEADER = 'X-IAF-ORIGIN-SERVICE';\nexport const USER_PERMISSIONS_HEADER = 'x-af-user-permissions';\nexport const LOWER_CASE_ORIGIN_HEADER = ORIGIN_HEADER.toLowerCase();\nexport const AUTOFLEET_APPS_SECRET_HEADER = 'x-autofleet-apps-secret';\n","import type { IncomingHttpHeaders } from 'node:http';\nimport { getCurrentContext } from '@autofleet/outbreak';\nimport ApiUser, { CONTEXTS_IDS_HEADER, ELEVATED_PERMISSIONS_HEADER, type UserPayload } from './ApiUser';\nimport {\n IDENTITY_MS,\n USER_OBJECT,\n USER_TRACING_HEADER,\n ORIGIN_HEADER,\n LOWER_CASE_ORIGIN_HEADER,\n} from './const';\n\nexport type CustomPermissionLoader = (userId: string) => Promise<UserPayload>;\nexport interface AuthFromUserIdHeaderOptions {\n eagerLoadUserPermissions?: boolean;\n eagerLoadUserPermissionsLegacy?: boolean;\n customPermissionLoader?: CustomPermissionLoader;\n}\n\nexport const authFromUserIdHeader = async (options: AuthFromUserIdHeaderOptions, headers: IncomingHttpHeaders): Promise<ApiUser | undefined> => {\n const originHeader = headers[ORIGIN_HEADER] || headers[LOWER_CASE_ORIGIN_HEADER] || '';\n if (!Array.isArray(originHeader) && originHeader.toLowerCase() === IDENTITY_MS) {\n return undefined;\n }\n const {\n eagerLoadUserPermissions,\n eagerLoadUserPermissionsLegacy,\n customPermissionLoader,\n } = options;\n const userId = headers[USER_TRACING_HEADER] as string;\n if (!userId || Array.isArray(userId)) {\n return undefined;\n }\n\n const elevatedPermissionsFromHeader = headers[ELEVATED_PERMISSIONS_HEADER]?.length > 0 ? JSON.parse(headers[ELEVATED_PERMISSIONS_HEADER] as string) : {};\n const contextIds = (headers?.[CONTEXTS_IDS_HEADER] as string)?.split(',');\n\n const userObject = new ApiUser(userId, 'user', elevatedPermissionsFromHeader, contextIds);\n if (eagerLoadUserPermissions) {\n if (customPermissionLoader) {\n await userObject.useCustomPermissionLoader(customPermissionLoader);\n } else {\n await userObject.getUserPermissions();\n }\n }\n\n if (eagerLoadUserPermissionsLegacy) {\n await userObject.getUserPermissionsLegacy();\n }\n\n getCurrentContext().nonHeaderContext?.set(USER_OBJECT, userObject);\n return userObject;\n};\n","import type { Handler, Request } from 'express';\nimport { getCurrentContext, newTrace, traceTypes } from '@autofleet/outbreak';\nimport jwt from 'jsonwebtoken';\nimport ApiUser, { CONTEXTS_IDS_HEADER } from './ApiUser';\nimport { decodeAppBearer } from '../app-auth';\nimport AppDoesNotExist from '../exceptions/appDoesNotExist';\nimport { decodeBearer, getAuthFromBearer } from '../utils';\nimport {\n ACCESS_TOKEN,\n USER_OBJECT,\n USER_TRACING_HEADER,\n USER_PERMISSIONS_HEADER,\n AUTOFLEET_APPS_SECRET_HEADER,\n} from './const';\nimport { authFromUserIdHeader, AuthFromUserIdHeaderOptions } from './common';\n\ndeclare module 'express-serve-static-core' {\n // eslint-disable-next-line @typescript-eslint/no-shadow\n interface Request {\n user: ApiUser;\n }\n}\n\nexport const middleware = (options: AuthFromUserIdHeaderOptions = {}): Handler => async (req, res, next): Promise<any> => {\n try {\n const userObject = await authFromUserIdHeader(options, req.headers);\n if (userObject) {\n req.user = userObject;\n // Added in order to support outbreak.\n // @ts-expect-error we are setting an object onto the request headers.\n req.headers[USER_PERMISSIONS_HEADER] = userObject;\n }\n\n next();\n } catch (e) {\n res.status(401).json({ error: 'cannot authenticate user' });\n }\n};\n\nexport const middlewareWithDecode = (options: {\n eagerLoadUserPermissions?: boolean;\n eagerLoadUserPermissionsLegacy?: boolean;\n returnErrorIfNoToken?: boolean\n} = {}): Handler => async (req, res, next): Promise<void> => {\n const {\n eagerLoadUserPermissions,\n eagerLoadUserPermissionsLegacy,\n returnErrorIfNoToken,\n } = options;\n let decoded;\n if (req.headers.authorization) {\n try {\n decoded = await decodeBearer(req.headers.authorization);\n } catch (e) {\n if (e instanceof jwt.TokenExpiredError) {\n res.status(401).json({ errors: ['Access token expired'] });\n } else if (e instanceof jwt.JsonWebTokenError) {\n res.status(400).json({ errors: [e.message] });\n } else {\n res.status(500).json({ errors: ['Server error while parsing token'] });\n }\n return;\n }\n const userId = decoded?.user?.id;\n\n if (userId) {\n req.headers[USER_TRACING_HEADER] = userId;\n }\n\n const contextIds = (req.headers?.[CONTEXTS_IDS_HEADER] as string)?.split(',');\n const userObject = new ApiUser(userId, decoded?.user?.accountType, undefined, contextIds);\n\n if (eagerLoadUserPermissions || eagerLoadUserPermissionsLegacy) {\n await Promise.all([\n eagerLoadUserPermissions && userObject.getUserPermissions(),\n eagerLoadUserPermissionsLegacy && userObject.getUserPermissionsLegacy(),\n ]);\n }\n\n req.user = userObject;\n getCurrentContext().nonHeaderContext?.set(USER_OBJECT, userObject);\n\n // Added in order to support outbreak.\n // @ts-expect-error we are setting an object onto the request headers.\n req.headers[USER_PERMISSIONS_HEADER] = userObject;\n } else if (returnErrorIfNoToken) {\n res.status(401).json({ errors: ['No token provided'] });\n return;\n }\n next();\n};\n\nexport const appMiddleware = (options: {\n appId: string,\n clientSecret: string\n}): Handler => async (req, res, next): Promise<void> => {\n const {\n appId,\n clientSecret,\n } = options;\n let decoded;\n\n if (!req.headers.authorization) {\n res.status(401).json({ errors: ['No token provided'] });\n return;\n }\n\n try {\n decoded = await decodeAppBearer(req.headers.authorization, appId);\n if (!decoded) {\n throw new AppDoesNotExist();\n }\n } catch (e) {\n if (e instanceof jwt.TokenExpiredError) {\n res.status(401).json({ errors: ['Access token expired'] });\n return;\n }\n if ([jwt.JsonWebTokenError, AppDoesNotExist].some((Err) => e instanceof Err)) {\n res.status(400).json({ errors: [e.message] });\n return;\n }\n res.status(500).json({ errors: ['Server error while parsing token'] });\n return;\n }\n const userId = decoded?.userId;\n if (userId) {\n req.headers[USER_TRACING_HEADER] = userId;\n }\n\n const userObject = new ApiUser(userId);\n\n if (appId) {\n req.headers[AUTOFLEET_APPS_SECRET_HEADER] = clientSecret;\n // Won't work until we find a better solution for identity ms\n await userObject.getUserAppPermissions(appId, clientSecret);\n }\n\n req.user = userObject;\n const currentTraceContext = getCurrentContext().nonHeaderContext;\n currentTraceContext?.set(USER_OBJECT, userObject);\n currentTraceContext?.set(ACCESS_TOKEN, getAuthFromBearer(req.headers.authorization));\n\n // Added in order to support outbreak.\n // @ts-expect-error we are setting an object onto the request headers.\n req.headers[USER_PERMISSIONS_HEADER] = userObject;\n\n next();\n};\n\nexport const eagerLoadPermissionsMiddleware: Handler = async (req, res, next) => {\n await req.user.getUserPermissions();\n next();\n};\n\nexport const getDecodedBearer = (req: Request) => {\n if (!req.headers.authorization) {\n return null;\n }\n return decodeBearer(req.headers.authorization);\n};\n\nexport const createOrSetRabbitTrace = async (trace: ReturnType<typeof newTrace> | undefined, userId: string | undefined) => {\n const userObject = new ApiUser(userId);\n\n await userObject.getUserPermissions();\n // eslint-disable-next-line no-param-reassign\n trace ??= newTrace(traceTypes.RABBIT);\n trace.nonHeaderContext.set(USER_OBJECT, userObject);\n};\n\nexport default ApiUser;\n","import type { FastifyPluginCallback } from 'fastify';\nimport type ApiUser from './ApiUser';\nimport { AuthFromUserIdHeaderOptions, authFromUserIdHeader } from './common';\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n user?: ApiUser;\n }\n}\n\n// eslint-disable-next-line import/prefer-default-export\nexport const authFromUserIdHeaderPlugin: FastifyPluginCallback<AuthFromUserIdHeaderOptions> = (fastify, options, done) => {\n fastify.decorateRequest('user', undefined);\n fastify.addHook('onRequest', async (request, reply) => {\n try {\n const user = await authFromUserIdHeader(options, request.headers);\n if (user) {\n request.user = user;\n }\n } catch (e) {\n reply.status(401).send({ error: 'cannot authenticate user' });\n }\n });\n\n done();\n};\nauthFromUserIdHeaderPlugin[Symbol.for('skip-override')] = true; // Prevent Fastify from overriding the plugin\n","import { getCurrentContext } from '@autofleet/outbreak';\nimport { USER_OBJECT } from './user/const';\nimport ApiUser, { type UserPayload } from './user/ApiUser';\n\nexport const getUser = () : ApiUser | undefined => getCurrentContext().nonHeaderContext?.get(USER_OBJECT) as ApiUser | undefined;\n\nexport const isUserExist = () => getUser()?.id;\n\nconst checkUserPermissions = (\n entityId: string,\n entityType: Exclude<keyof UserPayload, 'accountType' | 'createdAt'>,\n) => !isUserExist() || Object.hasOwn(getUser()!.permissions[entityType], entityId);\n\nexport const checkFleetPermission = (fleetId: string) => checkUserPermissions(fleetId, 'fleets');\nexport const checkBusinessModelPermission = (businessModelId: string) => checkUserPermissions(businessModelId, 'businessModels');\nexport const checkDemandSourcePermission = (demandSourceId: string) => checkUserPermissions(demandSourceId, 'demandSources');\n","import type ApiUser from './user';\n\n// eslint-disable-next-line import/prefer-default-export\nexport class UnauthorizedAccessError extends Error {\n constructor(public user: ApiUser | null = null, message = 'UnauthorizedAccessError') {\n super(message);\n this.name = 'UnauthorizedAccessError';\n }\n}\n","import jwt from 'jsonwebtoken';\n\nexport const AUTHORIZATION_METHODS = {\n NONE: 'NONE',\n BASIC: 'BASIC',\n JWT: 'JWT',\n};\n\nconst AUTHORIZATION_ACTIONS = {\n [AUTHORIZATION_METHODS.NONE]: () => undefined,\n [AUTHORIZATION_METHODS.BASIC]: (authorizationSettings: any) => {\n const { username, password } = authorizationSettings;\n const encodedCredentials = Buffer.from(`${username}:${password}`).toString('base64');\n return `Basic ${encodedCredentials}`;\n },\n [AUTHORIZATION_METHODS.JWT]: (authorizationSettings: any) => {\n const { secret } = authorizationSettings;\n if (secret) {\n return `Bearer ${jwt.sign({}, secret, { expiresIn: 10 })}`;\n }\n return undefined;\n },\n};\n\nexport const getAuthorizationHeader = (authorizationSettings: { method: string } | undefined): string | undefined => {\n const authorizationMethod = authorizationSettings?.method;\n\n if (!authorizationMethod || !AUTHORIZATION_ACTIONS[authorizationMethod]) {\n return undefined;\n }\n\n return AUTHORIZATION_ACTIONS[authorizationMethod](authorizationSettings);\n};\n","import { evaluatePermissions } from './SDK/evaluatePermissions';\nimport { requirePermissions } from './middleware/requirePermissions';\n\nexport const sdk = {\n evaluatePermissions,\n};\n\nexport const middlewares = {\n requirePermissions,\n};\n\nexport default {\n sdk,\n middlewares,\n};\n","import NodeCache from 'node-cache';\n\ninterface EntityPermissions {\n [key: string]: string[];\n}\n\nexport class PermissionCache {\n private cache: NodeCache;\n\n /**\n * Creates a new PermissionCache instance\n * @param cache - Optional NodeCache instance. If not provided, creates a new one with default TTL of 10 seconds\n */\n constructor(cache?: NodeCache) {\n this.cache = cache || new NodeCache({ stdTTL: 10 });\n }\n\n /**\n * Retrieves user permissions for multiple contexts from cache\n * @param userId - The user identifier\n * @param contextIds - Array of context identifiers to fetch permissions for\n * @returns Promise that resolves to an object mapping context IDs to permission arrays\n */\n public async getUserPermissions(userId: string, contextIds: string[]): Promise<EntityPermissions> {\n try {\n const cacheKey = (contextId) => `perm-${userId}-${contextId}`;\n\n return await this.cache.mget(contextIds.map(cacheKey)) as EntityPermissions;\n } catch (error) {\n return {};\n }\n }\n\n /**\n * Stores user permissions for multiple contexts in cache\n * @param userId - The user identifier\n * @param PermissionsByContextId - Object mapping context IDs to permission arrays\n * @param ttl - Optional time to live in seconds. Defaults to 10 seconds\n * @returns Promise that resolves to an object indicating success/failure\n */\n public async setUserPermissions(userId: string, PermissionsByContextId: EntityPermissions, ttl?: number): Promise<{ success: boolean }> {\n try {\n const cacheKey = (contextId) => `perm-${userId}-${contextId}`;\n\n const cacheEntries = Object.entries(PermissionsByContextId).map(([contextId, permissions]) => ({\n key: cacheKey(contextId),\n val: permissions,\n ttl: ttl ?? 10,\n }));\n\n await this.cache.mset(cacheEntries);\n\n return { success: true };\n } catch (error) {\n return { success: false };\n }\n }\n\n /**\n * Retrieves seen permissions status for multiple contexts from cache.\n * \"Seen\" permissions indicate that a user has already been evaluated for a specific set of\n * required permissions in a given context, avoiding redundant permission checks.\n * @param userId - The user identifier\n * @param contextIds - Array of context identifiers to check\n * @param requiredPermissions - Array of required permissions to check if previously evaluated\n * @returns Promise that resolves to an object mapping context IDs to boolean values indicating if permissions were previously evaluated\n */\n public async getSeenPermissions(userId: string, contextIds: string[], requiredPermissions: string[]): Promise<Record<string, boolean>> {\n try {\n const sortedPermissions = requiredPermissions.sort().join(',');\n const seenKey = (contextId: string) => `seen-${userId}-${contextId}-${sortedPermissions}`;\n\n return await this.cache.mget(contextIds.map(seenKey)) as Record<string, boolean>;\n } catch (error) {\n return {};\n }\n }\n\n /**\n * Marks permissions as seen for multiple contexts in cache.\n * \"Seen\" permissions are used to track that a user has already been evaluated for a specific\n * set of required permissions in given contexts, preventing duplicate permission evaluations.\n * @param userId - The user identifier\n * @param contextIds - Array of context identifiers to mark as seen\n * @param requiredPermissions - Array of required permissions that have been evaluated\n * @param ttl - Optional time to live in seconds. Defaults to 10 seconds\n * @returns Promise that resolves to an object indicating success/failure\n */\n public async setSeenPermissions(userId: string, contextIds: string[], requiredPermissions: string[], ttl?: number): Promise<{ success: boolean }> {\n try {\n const sortedPermissions = requiredPermissions.sort().join(',');\n const seenKey = (contextId: string) => `seen-${userId}-${contextId}-${sortedPermissions}`;\n\n const cacheEntries = contextIds.map((contextId) => ({\n key: seenKey(contextId),\n val: true,\n ttl: ttl ?? 10,\n }));\n\n await this.cache.mset(cacheEntries);\n\n return { success: true };\n } catch (error) {\n return { success: false };\n }\n }\n}\n\nexport const permissionCache = new PermissionCache();\n","export const PERMISSIONS_EVALUATION_OPERATORS = {\n AND: 'and',\n OR: 'or',\n};\n\nexport const PERMISSION_ERROR_TYPES = {\n USER_NOT_FOUND: 'USER_NOT_FOUND',\n INSUFFICIENT_PERMISSIONS: 'INSUFFICIENT_PERMISSIONS',\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n API_ERROR: 'API_ERROR',\n NO_REQUIRED_PERMISSIONS: 'NO_REQUIRED_PERMISSIONS',\n UNAUTHORIZED: 'UNAUTHORIZED',\n BAD_REQUEST: 'BAD_REQUEST',\n INTERNAL_ERROR: 'INTERNAL_ERROR',\n};\n\nexport const PERMISSION_ERROR_MESSAGES = {\n USER_NOT_FOUND: 'User not found',\n INSUFFICIENT_PERMISSIONS: 'User does not have sufficient permissions',\n VALIDATION_ERROR: 'Validation error occurred',\n API_ERROR: 'API error occurred',\n NO_REQUIRED_PERMISSIONS: 'No required permissions provided for evaluation',\n UNAUTHORIZED: 'User is not authorized to perform this action',\n BAD_REQUEST: 'Bad request, please check the input parameters',\n INTERNAL_ERROR: 'Internal server error occurred while checking permissions',\n};\n","import { getUser } from '../../check-permission';\nimport { IdentityNetwork } from '../../services';\nimport {\n PermissionsEvaluationOperator,\n type EvaluatePermissionsParams,\n type PermissionsEvaluationByContextId,\n type PermissionCheckResult,\n type ResolvePermissionsParams,\n type Logger,\n PermissionsByContextId,\n} from './types';\nimport { type PermissionErrorType } from './errors';\nimport { permissionCache } from './permissionCache';\nimport { PERMISSIONS_EVALUATION_OPERATORS, PERMISSION_ERROR_TYPES } from './consts';\n\n/**\n * Evaluates whether user permissions meet requirements based on AND/OR operator\n * @param permissions - User's actual permissions\n * @param requiredPermissions - Required permissions to check against\n * @param operator - {@link PermissionsEvaluationOperator} AND (all required) or OR (at least one required)\n * @returns true if permissions meet requirements\n */\nconst evaluatePermissionsByOperator = (\n permissions: string[],\n requiredPermissions: string[],\n operator: PermissionsEvaluationOperator,\n): boolean => {\n const permissionsSet = new Set(permissions);\n const matchingPermissions = requiredPermissions.filter((permission) => permissionsSet.has(permission));\n\n return operator === PERMISSIONS_EVALUATION_OPERATORS.AND\n ? matchingPermissions.length === requiredPermissions.length // All required permissions must be present\n : matchingPermissions.length > 0; // At least one required permission must be present\n};\n\n/**\n * Creates empty permissions result for cases with no required permissions\n * @param contextIds - Context IDs to create results for\n * @returns {@link PermissionsEvaluationByContextId} with empty permissions and granted access\n */\nconst createEmptyPermissionsResult = (contextIds: string[]): PermissionsEvaluationByContextId => Object.fromEntries(\n contextIds.map((contextId) => [\n contextId,\n { permissions: [], hasRequiredPermissions: true },\n ]),\n);\n\n/**\n * Checks if permission requirements are met across all contexts\n * @param permissionsEvaluationByContextId - {@link PermissionsEvaluationByContextId} Permission evaluation results by context\n * @param requireAll - Whether all contexts must satisfy requirements (true) or just one (false)\n * @returns true if requirements are met\n */\nexport const checkAuthorizeRequirements = (permissionsEvaluationByContextId: PermissionsEvaluationByContextId, requireAll: boolean) => {\n const permissionsEvaluationValues = Object.values(permissionsEvaluationByContextId);\n\n if (requireAll) {\n return permissionsEvaluationValues.every((evaluation) => evaluation.hasRequiredPermissions);\n }\n return permissionsEvaluationValues.some((evaluation) => evaluation.hasRequiredPermissions);\n};\n\n/**\n * Resolves permissions from Identity Service API\n * @param params - {@link ResolvePermissionsParams}\n * @returns {@link PermissionsEvaluationByContextId} Permission evaluation results by context ID\n */\nexport const resolvePermissions = async ({\n user,\n contextIds,\n requiredPermissions,\n options,\n}: ResolvePermissionsParams): Promise<PermissionsEvaluationByContextId> => {\n if (!requiredPermissions?.length) {\n return createEmptyPermissionsResult(contextIds);\n }\n\n const response = await IdentityNetwork.post('/api/v1/permissions/resolve', {\n userId: user.id,\n contextIds,\n requiredPermissions,\n }, {\n timeout: options.timeout,\n });\n\n const { data }: { data: PermissionsEvaluationByContextId } = response;\n\n if (!Object.keys(data || {}).length) {\n throw new Error('Failed to resolve permissions');\n }\n\n if (options.permissionsEvaluationOperator === PERMISSIONS_EVALUATION_OPERATORS.AND) {\n return data;\n }\n\n const permissionsEvaluationByContextId: PermissionsEvaluationByContextId = {};\n Object.entries(data).forEach(([contextId, evaluation]) => {\n const permissions = evaluation?.permissions || [];\n const hasRequiredPermissions = evaluatePermissionsByOperator(\n permissions,\n requiredPermissions,\n options.permissionsEvaluationOperator,\n );\n\n permissionsEvaluationByContextId[contextId] = {\n permissions,\n hasRequiredPermissions,\n };\n });\n\n return permissionsEvaluationByContextId;\n};\n\n/**\n * Resolves permissions from user's cached permissions\n * @param params - {@link ResolvePermissionsParams}\n * @returns {@link PermissionsEvaluationByContextId} Permission evaluation results by context ID from cache\n */\nexport const resolvePermissionsFromCache = async ({\n user,\n contextIds,\n requiredPermissions,\n options,\n}: ResolvePermissionsParams): Promise<PermissionsEvaluationByContextId> => {\n const cachedPermissions = await permissionCache.getUserPermissions(user.id, contextIds);\n\n if (!Object.keys(cachedPermissions || {}).length) {\n return {};\n }\n\n const permissionsEvaluationByContextId: PermissionsEvaluationByContextId = {};\n\n Object.entries(cachedPermissions).forEach(([contextId, permissions]) => {\n const hasRequiredPermissions = evaluatePermissionsByOperator(\n permissions,\n requiredPermissions,\n options.permissionsEvaluationOperator,\n );\n\n permissionsEvaluationByContextId[contextId] = {\n permissions,\n hasRequiredPermissions,\n };\n });\n\n return permissionsEvaluationByContextId;\n};\n\nconst validateInput = (contextIds: string[]): string[] => {\n const errors: string[] = [];\n\n if (!contextIds?.length) {\n errors.push('contextIds cannot be empty');\n }\n\n return errors;\n};\n\nconst createErrorResult = (\n error: PermissionErrorType,\n requiredPermissions: string[],\n contextIds: string[],\n message?: string,\n): PermissionCheckResult => ({\n isAuthorized: false,\n error,\n resolvedPermissions: {},\n requiredPermissions,\n contextIds,\n ...(message && { message }),\n});\n\n/**\n * Caches permission results based on whether they meet requirements\n */\nconst cachePermissionsResults = async (\n userId: string,\n resolvedPermissions: PermissionsEvaluationByContextId,\n requiredPermissions: string[],\n): Promise<void> => {\n const permissionsToCache: PermissionsByContextId = {};\n const contextIdsWithoutPermissions: string[] = [];\n\n Object.entries(resolvedPermissions).forEach(([contextId, evaluation]) => {\n if (evaluation?.permissions) {\n if (evaluation.hasRequiredPermissions) {\n permissionsToCache[contextId] = evaluation.permissions;\n } else {\n contextIdsWithoutPermissions.push(contextId);\n }\n }\n });\n\n if (Object.keys(permissionsToCache).length > 0) {\n await permissionCache.setUserPermissions(userId, permissionsToCache);\n }\n\n if (contextIdsWithoutPermissions.length > 0) {\n await permissionCache.setSeenPermissions(userId, contextIdsWithoutPermissions, requiredPermissions);\n }\n};\n\n/**\n * Filters context IDs to only those that haven't been seen before\n * Seen context IDs are those for which the user has already been denied permissions\n */\nconst getUnseenContextIds = async (\n userId: string,\n contextIds: string[],\n requiredPermissions: string[],\n): Promise<string[]> => {\n const seenPermissions = await permissionCache.getSeenPermissions(userId, contextIds, requiredPermissions);\n return contextIds.filter((contextId) => !seenPermissions[`seen-${userId}-${contextId}-${requiredPermissions.sort().join(',')}`]);\n};\n\n/**\n * Creates entries for \"seen\" contexts that were previously denied permissions\n * @param uncachedContextIds - Context IDs that weren't found in cache\n * @param unseenContextIds - Context IDs that haven't been processed before\n * @returns Object with entries for seen contexts marked as having no required permissions\n */\nconst createSeenContextEntries = (\n uncachedContextIds: string[],\n unseenContextIds: string[],\n): PermissionsEvaluationByContextId => {\n const seenContextIds = uncachedContextIds.filter((contextId) => !unseenContextIds.includes(contextId));\n const seenEntries: PermissionsEvaluationByContextId = {};\n\n seenContextIds.forEach((contextId) => {\n seenEntries[contextId] = {\n permissions: [],\n hasRequiredPermissions: false,\n };\n });\n\n return seenEntries;\n};\n\n/**\n * Processes cached permissions into evaluation format\n * @param cachedPermissions - Raw permissions from cache\n * @param requiredPermissions - Required permissions to evaluate against\n * @param operator - Evaluation operator (AND/OR)\n * @returns Processed permissions evaluation\n */\nconst processCachedPermissions = (\n cachedPermissions: Record<string, string[]>,\n requiredPermissions: string[],\n operator: PermissionsEvaluationOperator,\n): PermissionsEvaluationByContextId => {\n const processedPermissions: PermissionsEvaluationByContextId = {};\n\n if (Object.keys(cachedPermissions || {}).length) {\n Object.entries(cachedPermissions).forEach(([contextId, permissions]) => {\n const hasRequiredPermissions = evaluatePermissionsByOperator(\n permissions,\n requiredPermissions,\n operator,\n );\n\n processedPermissions[contextId] = {\n permissions,\n hasRequiredPermissions,\n };\n });\n }\n\n return processedPermissions;\n};\n\n/**\n * Calls the Identity API to resolve permissions for unseen contexts\n * @param userId - User ID\n * @param contextIds - Context IDs to resolve\n * @param requiredPermissions - Required permissions\n * @param options - API call options\n * @returns Resolved permissions from API\n */\nconst callIdentityAPI = async (\n userId: string,\n contextIds: string[],\n requiredPermissions: string[],\n options: { permissionsEvaluationOperator: PermissionsEvaluationOperator; timeout: number },\n): Promise<PermissionsEvaluationByContextId> => {\n const response = await IdentityNetwork.post('/api/v1/permissions/resolve', {\n userId,\n contextIds,\n requiredPermissions,\n }, {\n timeout: options.timeout,\n });\n\n const { data }: { data: PermissionsEvaluationByContextId } = response;\n\n if (!Object.keys(data || {}).length) {\n throw new Error('Failed to resolve permissions');\n }\n\n // If using AND operator, return data as-is. For OR, re-evaluate.\n if (options.permissionsEvaluationOperator === PERMISSIONS_EVALUATION_OPERATORS.AND) {\n return data;\n }\n\n // Re-evaluate with OR operator\n const reEvaluatedPermissions: PermissionsEvaluationByContextId = {};\n Object.entries(data).forEach(([contextId, evaluation]) => {\n const permissions = evaluation?.permissions || [];\n const hasRequiredPermissions = evaluatePermissionsByOperator(\n permissions,\n requiredPermissions,\n options.permissionsEvaluationOperator,\n );\n\n reEvaluatedPermissions[contextId] = {\n permissions,\n hasRequiredPermissions,\n };\n });\n\n return reEvaluatedPermissions;\n};\n\n/**\n * Validates user context and required permissions for evaluation\n * @param contextIds - Context IDs to validate\n * @param requiredPermissions - Required permissions to validate\n * @param userId - User ID to validate\n * @param logger - Logger instance for warnings\n * @returns Error result if validation fails, null if validation passes\n */\nconst validateEvaluationInput = (\n contextIds: string[],\n requiredPermissions: string[],\n userId: string | null,\n logger: Logger,\n): PermissionCheckResult | null => {\n const validationErrors = validateInput(contextIds);\n if (validationErrors.length) {\n return createErrorResult(PERMISSION_ERROR_TYPES.VALIDATION_ERROR, requiredPermissions, contextIds, validationErrors.join(', '));\n }\n\n if (!userId) {\n logger?.warn('User not found in context, cannot check permissions', {\n contextIds,\n requiredPermissions,\n });\n return createErrorResult(PERMISSION_ERROR_TYPES.USER_NOT_FOUND, requiredPermissions, contextIds);\n }\n\n if (!requiredPermissions?.length) {\n logger?.info('No requiredPermissions provided', {\n userId,\n contextIds,\n });\n return {\n isAuthorized: false,\n userId,\n resolvedPermissions: {},\n requiredPermissions,\n contextIds,\n error: PERMISSION_ERROR_TYPES.NO_REQUIRED_PERMISSIONS,\n };\n }\n\n return null;\n};\n\n/**\n * Resolves permissions from multiple sources (cache, seen contexts, API)\n * @param userId - User ID\n * @param contextIds - Context IDs to resolve permissions for\n * @param requiredPermissions - Required permissions to check\n * @param options - Evaluation options\n * @returns Combined permissions from all sources\n */\nconst resolveAllPermissions = async (\n userId: string,\n contextIds: string[],\n requiredPermissions: string[],\n options: { permissionsEvaluationOperator: PermissionsEvaluationOperator; timeout: number },\n): Promise<PermissionsEvaluationByContextId> => {\n // Process cached permissions\n const cachedPermissions = await permissionCache.getUserPermissions(userId, contextIds);\n const resolvedPermissionsFromCache = processCachedPermissions(\n cachedPermissions,\n requiredPermissions,\n options.permissionsEvaluationOperator,\n );\n let resolvedPermissions = { ...resolvedPermissionsFromCache };\n\n // Handle uncached contexts\n const uncachedContextIds = contextIds.filter((contextId) => !resolvedPermissionsFromCache[contextId]);\n const unseenContextIds = await getUnseenContextIds(userId, uncachedContextIds, requiredPermissions);\n\n // Add entries for seen contexts (previously denied)\n const seenContextEntries = createSeenContextEntries(uncachedContextIds, unseenContextIds);\n resolvedPermissions = { ...resolvedPermissions, ...seenContextEntries };\n\n // Resolve unseen contexts from API\n if (unseenContextIds.length) {\n const resolvedPermissionsFromIdentityMS = await callIdentityAPI(\n userId,\n unseenContextIds,\n requiredPermissions,\n options,\n );\n\n resolvedPermissions = {\n ...resolvedPermissions,\n ...resolvedPermissionsFromIdentityMS,\n };\n\n await cachePermissionsResults(userId, resolvedPermissionsFromIdentityMS, requiredPermissions);\n }\n\n return resolvedPermissions;\n};\n\n/**\n * Main SDK function to evaluate user permissions\n * Checks both cached and API-resolved permissions to determine access\n * @param params - {@link EvaluatePermissionsParams}\n * @returns {@link PermissionCheckResult} Detailed permission check result with access status and context\n */\nexport const evaluatePermissions = async ({\n requiredPermissions,\n contextIds,\n logger,\n userId,\n options: {\n requireAll = true,\n permissionsEvaluationOperator = PERMISSIONS_EVALUATION_OPERATORS.AND,\n timeout = 10000,\n },\n}: EvaluatePermissionsParams): Promise<PermissionCheckResult> => {\n const resolvedUserId = userId || getUser()?.id || null;\n\n const validationError = validateEvaluationInput(contextIds, requiredPermissions, resolvedUserId, logger);\n if (validationError) {\n return validationError;\n }\n\n const resolvedPermissions = await resolveAllPermissions(\n resolvedUserId!,\n contextIds,\n requiredPermissions,\n { permissionsEvaluationOperator, timeout },\n );\n\n const isAuthorized = checkAuthorizeRequirements(resolvedPermissions, requireAll);\n\n logger?.info('Resolved permissions', {\n userId: resolvedUserId,\n requiredPermissions,\n isAuthorized,\n requireAll,\n permissionsEvaluationOperator,\n contextIds,\n });\n\n return {\n isAuthorized,\n userId: resolvedUserId!,\n resolvedPermissions,\n requiredPermissions,\n contextIds,\n ...(isAuthorized ? {} : { error: PERMISSION_ERROR_TYPES.INSUFFICIENT_PERMISSIONS }),\n };\n};\n\nexport default evaluatePermissions;\n","import type { Request, Response, NextFunction } from 'express';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\nimport { evaluatePermissions } from '../SDK/evaluatePermissions';\nimport type { EvaluatePermissionsOpts } from '../SDK/types';\nimport { getUser } from '../../check-permission';\nimport { CONTEXTS_IDS_HEADER } from '../../user/ApiUser';\nimport { PERMISSION_ERROR_MESSAGES, PERMISSION_ERROR_TYPES, PERMISSIONS_EVALUATION_OPERATORS } from '../SDK/consts';\n\nexport interface RequirePermissionsOptions extends EvaluatePermissionsOpts {\n logger?: LoggerInstanceManager;\n}\n\nconst getContextIds = (req: Request): string[] => {\n const contextIdsFromHeader = (req.headers?.[CONTEXTS_IDS_HEADER] as string)?.split(',') || [];\n const contextIdsFromQuery = (req.query?.contextIds as string)?.split(',') || [];\n const contextIdsFromBody = (req.body?.contextIds as string[]) || [];\n\n return Array.from(new Set([...contextIdsFromHeader, ...contextIdsFromQuery, ...contextIdsFromBody])).filter(Boolean);\n};\n\nconst handleError = (\n errorLabel: string,\n message: string,\n code: number,\n enforce: boolean,\n res: Response,\n req: Request,\n next: NextFunction,\n logger?: LoggerInstanceManager,\n additionalInfo?: Record<string, unknown>,\n) => {\n if (enforce) {\n logger?.error(message, {\n url: req.url,\n method: req.method,\n requiredPermissions: additionalInfo?.requiredPermissions || [],\n ...additionalInfo,\n });\n\n return res.status(code).json({\n error: errorLabel,\n message,\n ...(additionalInfo?.requiredPermissions && { requiredPermissions: additionalInfo.requiredPermissions }),\n });\n }\n\n logger?.warn(message, {\n url: req.url,\n method: req.method,\n requiredPermissions: additionalInfo?.requiredPermissions || [],\n ...additionalInfo,\n });\n return next();\n};\n\n/**\n * Express middleware that requires specific permissions for route access\n *\n * @param requiredPermissions - Array of permissions required to access the route\n * @param options - Configuration options for permission checking\n * @returns Express middleware function\n */\nexport const requirePermissions = (\n requiredPermissions: string[],\n options: RequirePermissionsOptions = {\n enforce: false,\n requireAll: true,\n permissionsEvaluationOperator: PERMISSIONS_EVALUATION_OPERATORS.AND,\n },\n) => async (req: Request, res: Response, next: NextFunction) => {\n try {\n const {\n logger,\n enforce,\n requireAll,\n permissionsEvaluationOperator,\n } = options;\n\n const handleErrorWrapper = (errorLabel: string, message: string, code: number) => handleError(\n errorLabel,\n message,\n code,\n enforce,\n res,\n req,\n next,\n logger,\n { requiredPermissions },\n );\n\n const user = getUser();\n if (!user?.id) {\n return handleErrorWrapper(\n PERMISSION_ERROR_TYPES.UNAUTHORIZED,\n PERMISSION_ERROR_MESSAGES.UNAUTHORIZED,\n 401,\n );\n }\n\n const contextIds: string[] = getContextIds(req);\n if (!contextIds?.length) {\n return handleErrorWrapper(\n PERMISSION_ERROR_TYPES.BAD_REQUEST,\n PERMISSION_ERROR_MESSAGES.BAD_REQUEST,\n 400,\n );\n }\n\n // Evaluate permissions using SDK\n const result = await evaluatePermissions({\n requiredPermissions,\n contextIds,\n logger,\n userId: user.id,\n options: {\n requireAll: requireAll ?? true,\n permissionsEvaluationOperator: permissionsEvaluationOperator ?? PERMISSIONS_EVALUATION_OPERATORS.AND,\n timeout: 10000,\n },\n });\n\n if (result.isAuthorized) {\n logger?.info('User has required permissions', {\n userId: user.id,\n requiredPermissions,\n contextIds,\n url: req.url,\n method: req.method,\n });\n return next();\n }\n\n if (!enforce) {\n logger?.warn('User does not have required permissions, skipping enforcement', {\n userId: user.id,\n requiredPermissions,\n contextIds,\n url: req.url,\n method: req.method,\n });\n return next();\n }\n\n return res.status(403).json({\n error: PERMISSION_ERROR_TYPES.INSUFFICIENT_PERMISSIONS,\n message: PERMISSION_ERROR_MESSAGES.INSUFFICIENT_PERMISSIONS,\n required: requiredPermissions,\n contexts: contextIds,\n userId: result.userId,\n });\n } catch (error) {\n const requestLogger = options.logger;\n requestLogger?.error('Error in requirePermissions middleware', {\n error,\n requiredPermissions,\n url: req.url,\n method: req.method,\n });\n\n if (!options.enforce) {\n options.logger?.error('Error during permission check, skipping enforcement', {\n error,\n url: req.url,\n method: req.method,\n });\n return next();\n }\n\n return res.status(500).json({\n error: PERMISSION_ERROR_TYPES.INTERNAL_ERROR,\n message: PERMISSION_ERROR_MESSAGES.INTERNAL_ERROR,\n });\n }\n};\n\nexport default requirePermissions;\n","import type { LoggerInstanceManager } from '@autofleet/logger';\nimport * as outbreak from '@autofleet/outbreak';\nimport User, {\n middleware,\n eagerLoadPermissionsMiddleware,\n middlewareWithDecode,\n getDecodedBearer,\n appMiddleware,\n createOrSetRabbitTrace,\n} from './user';\nimport { authFromUserIdHeaderPlugin } from './user/fastify';\nimport { type UserPayload, CONTEXTS_IDS_HEADER } from './user/ApiUser';\nimport {\n checkFleetPermission,\n checkBusinessModelPermission,\n checkDemandSourcePermission,\n isUserExist,\n getUser,\n} from './check-permission';\nimport { UnauthorizedAccessError } from './errors';\nimport { getRefreshTokenSecret, getTokenSecret } from './secret-getter';\nimport { AUTHORIZATION_METHODS, getAuthorizationHeader } from './authorization';\nimport * as permissions from './permissions';\n\nconst getCurrentPayload = outbreak.getCurrentContext;\n\ntype OutbreakOptions = Parameters<typeof outbreak.default>[0];\ntype LoggerWithContextMiddleware = Partial<Pick<LoggerInstanceManager, 'addContextMiddleware'>>;\nconst enableTracing = ({ outbreakOptions = {}, logger }: { outbreakOptions?: OutbreakOptions, logger?: LoggerWithContextMiddleware } = {}): void => {\n outbreak.default({\n headersPrefix: 'x-af',\n contextMiddlewareGetter: logger?.addContextMiddleware,\n ...outbreakOptions,\n });\n};\n\nconst { traceTypes, newTrace } = outbreak;\n\nexport {\n traceTypes,\n newTrace,\n enableTracing,\n User,\n middleware,\n middlewareWithDecode,\n eagerLoadPermissionsMiddleware,\n getCurrentPayload,\n getDecodedBearer,\n checkFleetPermission,\n checkBusinessModelPermission,\n checkDemandSourcePermission,\n isUserExist,\n getUser,\n getRefreshTokenSecret,\n getTokenSecret,\n UnauthorizedAccessError,\n appMiddleware,\n createOrSetRabbitTrace,\n outbreak,\n AUTHORIZATION_METHODS,\n getAuthorizationHeader,\n type UserPayload,\n CONTEXTS_IDS_HEADER,\n authFromUserIdHeaderPlugin,\n permissions,\n};\n\nexport default {\n traceTypes,\n newTrace,\n User,\n middleware,\n middlewareWithDecode,\n eagerLoadPermissionsMiddleware,\n getCurrentPayload,\n getDecodedBearer,\n checkFleetPermission,\n checkBusinessModelPermission,\n checkDemandSourcePermission,\n isUserExist,\n getUser,\n UnauthorizedAccessError,\n appMiddleware,\n createOrSetRabbitTrace,\n outbreak,\n AUTHORIZATION_METHODS,\n getAuthorizationHeader,\n CONTEXTS_IDS_HEADER,\n authFromUserIdHeaderPlugin,\n permissions,\n};\n"]}
|
package/lib/index.d.cts
CHANGED
|
@@ -2,7 +2,6 @@ import * as fastify from 'fastify';
|
|
|
2
2
|
import { FastifyPluginCallback } from 'fastify';
|
|
3
3
|
import * as express from 'express';
|
|
4
4
|
import { Handler, Request } from 'express';
|
|
5
|
-
import * as crypto from 'crypto';
|
|
6
5
|
import { LoggerInstanceManager } from '@autofleet/logger';
|
|
7
6
|
import * as outbreak from '@autofleet/outbreak';
|
|
8
7
|
import { newTrace as newTrace$1 } from '@autofleet/outbreak';
|
|
@@ -112,9 +111,86 @@ declare const getAuthorizationHeader: (authorizationSettings: {
|
|
|
112
111
|
method: string;
|
|
113
112
|
} | undefined) => string | undefined;
|
|
114
113
|
|
|
114
|
+
declare const PERMISSIONS_EVALUATION_OPERATORS: {
|
|
115
|
+
AND: string;
|
|
116
|
+
OR: string;
|
|
117
|
+
};
|
|
118
|
+
declare const PERMISSION_ERROR_TYPES: {
|
|
119
|
+
USER_NOT_FOUND: string;
|
|
120
|
+
INSUFFICIENT_PERMISSIONS: string;
|
|
121
|
+
VALIDATION_ERROR: string;
|
|
122
|
+
API_ERROR: string;
|
|
123
|
+
NO_REQUIRED_PERMISSIONS: string;
|
|
124
|
+
UNAUTHORIZED: string;
|
|
125
|
+
BAD_REQUEST: string;
|
|
126
|
+
INTERNAL_ERROR: string;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
type PermissionErrorType = typeof PERMISSION_ERROR_TYPES[keyof typeof PERMISSION_ERROR_TYPES];
|
|
130
|
+
|
|
131
|
+
type Logger = {
|
|
132
|
+
debug: (message: string, meta?: unknown) => void;
|
|
133
|
+
info: (message: string, meta?: unknown) => void;
|
|
134
|
+
warn: (message: string, meta?: unknown) => void;
|
|
135
|
+
error: (message: string, meta?: unknown) => void;
|
|
136
|
+
};
|
|
137
|
+
type PermissionsEvaluationOperator = typeof PERMISSIONS_EVALUATION_OPERATORS[keyof typeof PERMISSIONS_EVALUATION_OPERATORS];
|
|
138
|
+
type EvaluatePermissionsOpts = {
|
|
139
|
+
requireAll?: boolean;
|
|
140
|
+
timeout?: number;
|
|
141
|
+
enforce?: boolean;
|
|
142
|
+
permissionsEvaluationOperator?: PermissionsEvaluationOperator;
|
|
143
|
+
};
|
|
144
|
+
type EvaluatePermissionsParams = {
|
|
145
|
+
requiredPermissions: string[];
|
|
146
|
+
contextIds: string[];
|
|
147
|
+
logger: Logger;
|
|
148
|
+
options: EvaluatePermissionsOpts;
|
|
149
|
+
userId?: string;
|
|
150
|
+
};
|
|
151
|
+
type PermissionsEvaluation = {
|
|
152
|
+
permissions: string[];
|
|
153
|
+
hasRequiredPermissions: boolean;
|
|
154
|
+
};
|
|
155
|
+
type PermissionsEvaluationByContextId = Record<string, PermissionsEvaluation>;
|
|
156
|
+
type PermissionCheckResult = {
|
|
157
|
+
isAuthorized: boolean;
|
|
158
|
+
userId?: string;
|
|
159
|
+
resolvedPermissions: PermissionsEvaluationByContextId;
|
|
160
|
+
requiredPermissions: string[];
|
|
161
|
+
contextIds: string[];
|
|
162
|
+
error?: PermissionErrorType;
|
|
163
|
+
message?: string;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
interface RequirePermissionsOptions extends EvaluatePermissionsOpts {
|
|
167
|
+
logger?: LoggerInstanceManager;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
declare const sdk: {
|
|
171
|
+
evaluatePermissions: ({ requiredPermissions, contextIds, logger, userId, options: { requireAll, permissionsEvaluationOperator, timeout, }, }: EvaluatePermissionsParams) => Promise<PermissionCheckResult>;
|
|
172
|
+
};
|
|
173
|
+
declare const middlewares: {
|
|
174
|
+
requirePermissions: (requiredPermissions: string[], options?: RequirePermissionsOptions) => (req: express.Request, res: express.Response, next: express.NextFunction) => Promise<void | express.Response<any, Record<string, any>>>;
|
|
175
|
+
};
|
|
176
|
+
declare const _default$1: {
|
|
177
|
+
sdk: {
|
|
178
|
+
evaluatePermissions: ({ requiredPermissions, contextIds, logger, userId, options: { requireAll, permissionsEvaluationOperator, timeout, }, }: EvaluatePermissionsParams) => Promise<PermissionCheckResult>;
|
|
179
|
+
};
|
|
180
|
+
middlewares: {
|
|
181
|
+
requirePermissions: (requiredPermissions: string[], options?: RequirePermissionsOptions) => (req: express.Request, res: express.Response, next: express.NextFunction) => Promise<void | express.Response<any, Record<string, any>>>;
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
declare const permissions_middlewares: typeof middlewares;
|
|
186
|
+
declare const permissions_sdk: typeof sdk;
|
|
187
|
+
declare namespace permissions {
|
|
188
|
+
export { _default$1 as default, permissions_middlewares as middlewares, permissions_sdk as sdk };
|
|
189
|
+
}
|
|
190
|
+
|
|
115
191
|
declare const getCurrentPayload: () => {
|
|
116
192
|
type: "httpRequest" | "webSocket" | "rabbit" | "bull";
|
|
117
|
-
readonly id:
|
|
193
|
+
readonly id: `${string}-${string}-${string}-${string}-${string}`;
|
|
118
194
|
readonly context: Map<string, unknown>;
|
|
119
195
|
readonly nonHeaderContext: Map<string, unknown>;
|
|
120
196
|
} | Record<string, never>;
|
|
@@ -132,7 +208,7 @@ declare const traceTypes: {
|
|
|
132
208
|
};
|
|
133
209
|
declare const newTrace: (type: "httpRequest" | "webSocket" | "rabbit" | "bull") => {
|
|
134
210
|
type: "httpRequest" | "webSocket" | "rabbit" | "bull";
|
|
135
|
-
readonly id:
|
|
211
|
+
readonly id: `${string}-${string}-${string}-${string}-${string}`;
|
|
136
212
|
readonly context: Map<string, unknown>;
|
|
137
213
|
readonly nonHeaderContext: Map<string, unknown>;
|
|
138
214
|
};
|
|
@@ -146,7 +222,7 @@ declare const _default: {
|
|
|
146
222
|
};
|
|
147
223
|
newTrace: (type: "httpRequest" | "webSocket" | "rabbit" | "bull") => {
|
|
148
224
|
type: "httpRequest" | "webSocket" | "rabbit" | "bull";
|
|
149
|
-
readonly id:
|
|
225
|
+
readonly id: `${string}-${string}-${string}-${string}-${string}`;
|
|
150
226
|
readonly context: Map<string, unknown>;
|
|
151
227
|
readonly nonHeaderContext: Map<string, unknown>;
|
|
152
228
|
};
|
|
@@ -160,7 +236,7 @@ declare const _default: {
|
|
|
160
236
|
eagerLoadPermissionsMiddleware: express.Handler;
|
|
161
237
|
getCurrentPayload: () => {
|
|
162
238
|
type: "httpRequest" | "webSocket" | "rabbit" | "bull";
|
|
163
|
-
readonly id:
|
|
239
|
+
readonly id: `${string}-${string}-${string}-${string}-${string}`;
|
|
164
240
|
readonly context: Map<string, unknown>;
|
|
165
241
|
readonly nonHeaderContext: Map<string, unknown>;
|
|
166
242
|
} | Record<string, never>;
|
|
@@ -187,6 +263,7 @@ declare const _default: {
|
|
|
187
263
|
} | undefined) => string | undefined;
|
|
188
264
|
CONTEXTS_IDS_HEADER: string;
|
|
189
265
|
authFromUserIdHeaderPlugin: fastify.FastifyPluginCallback<AuthFromUserIdHeaderOptions>;
|
|
266
|
+
permissions: typeof permissions;
|
|
190
267
|
};
|
|
191
268
|
|
|
192
|
-
export { AUTHORIZATION_METHODS, CONTEXTS_IDS_HEADER, UnauthorizedAccessError, ApiUser as User, type UserPayload, appMiddleware, authFromUserIdHeaderPlugin, checkBusinessModelPermission, checkDemandSourcePermission, checkFleetPermission, createOrSetRabbitTrace, _default as default, eagerLoadPermissionsMiddleware, enableTracing, getAuthorizationHeader, getCurrentPayload, getDecodedBearer, getRefreshTokenSecret, getTokenSecret, getUser, isUserExist, middleware, middlewareWithDecode, newTrace, traceTypes };
|
|
269
|
+
export { AUTHORIZATION_METHODS, CONTEXTS_IDS_HEADER, UnauthorizedAccessError, ApiUser as User, type UserPayload, appMiddleware, authFromUserIdHeaderPlugin, checkBusinessModelPermission, checkDemandSourcePermission, checkFleetPermission, createOrSetRabbitTrace, _default as default, eagerLoadPermissionsMiddleware, enableTracing, getAuthorizationHeader, getCurrentPayload, getDecodedBearer, getRefreshTokenSecret, getTokenSecret, getUser, isUserExist, middleware, middlewareWithDecode, newTrace, permissions, traceTypes };
|
package/lib/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ import * as fastify from 'fastify';
|
|
|
2
2
|
import { FastifyPluginCallback } from 'fastify';
|
|
3
3
|
import * as express from 'express';
|
|
4
4
|
import { Handler, Request } from 'express';
|
|
5
|
-
import * as crypto from 'crypto';
|
|
6
5
|
import { LoggerInstanceManager } from '@autofleet/logger';
|
|
7
6
|
import * as outbreak from '@autofleet/outbreak';
|
|
8
7
|
import { newTrace as newTrace$1 } from '@autofleet/outbreak';
|
|
@@ -112,9 +111,86 @@ declare const getAuthorizationHeader: (authorizationSettings: {
|
|
|
112
111
|
method: string;
|
|
113
112
|
} | undefined) => string | undefined;
|
|
114
113
|
|
|
114
|
+
declare const PERMISSIONS_EVALUATION_OPERATORS: {
|
|
115
|
+
AND: string;
|
|
116
|
+
OR: string;
|
|
117
|
+
};
|
|
118
|
+
declare const PERMISSION_ERROR_TYPES: {
|
|
119
|
+
USER_NOT_FOUND: string;
|
|
120
|
+
INSUFFICIENT_PERMISSIONS: string;
|
|
121
|
+
VALIDATION_ERROR: string;
|
|
122
|
+
API_ERROR: string;
|
|
123
|
+
NO_REQUIRED_PERMISSIONS: string;
|
|
124
|
+
UNAUTHORIZED: string;
|
|
125
|
+
BAD_REQUEST: string;
|
|
126
|
+
INTERNAL_ERROR: string;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
type PermissionErrorType = typeof PERMISSION_ERROR_TYPES[keyof typeof PERMISSION_ERROR_TYPES];
|
|
130
|
+
|
|
131
|
+
type Logger = {
|
|
132
|
+
debug: (message: string, meta?: unknown) => void;
|
|
133
|
+
info: (message: string, meta?: unknown) => void;
|
|
134
|
+
warn: (message: string, meta?: unknown) => void;
|
|
135
|
+
error: (message: string, meta?: unknown) => void;
|
|
136
|
+
};
|
|
137
|
+
type PermissionsEvaluationOperator = typeof PERMISSIONS_EVALUATION_OPERATORS[keyof typeof PERMISSIONS_EVALUATION_OPERATORS];
|
|
138
|
+
type EvaluatePermissionsOpts = {
|
|
139
|
+
requireAll?: boolean;
|
|
140
|
+
timeout?: number;
|
|
141
|
+
enforce?: boolean;
|
|
142
|
+
permissionsEvaluationOperator?: PermissionsEvaluationOperator;
|
|
143
|
+
};
|
|
144
|
+
type EvaluatePermissionsParams = {
|
|
145
|
+
requiredPermissions: string[];
|
|
146
|
+
contextIds: string[];
|
|
147
|
+
logger: Logger;
|
|
148
|
+
options: EvaluatePermissionsOpts;
|
|
149
|
+
userId?: string;
|
|
150
|
+
};
|
|
151
|
+
type PermissionsEvaluation = {
|
|
152
|
+
permissions: string[];
|
|
153
|
+
hasRequiredPermissions: boolean;
|
|
154
|
+
};
|
|
155
|
+
type PermissionsEvaluationByContextId = Record<string, PermissionsEvaluation>;
|
|
156
|
+
type PermissionCheckResult = {
|
|
157
|
+
isAuthorized: boolean;
|
|
158
|
+
userId?: string;
|
|
159
|
+
resolvedPermissions: PermissionsEvaluationByContextId;
|
|
160
|
+
requiredPermissions: string[];
|
|
161
|
+
contextIds: string[];
|
|
162
|
+
error?: PermissionErrorType;
|
|
163
|
+
message?: string;
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
interface RequirePermissionsOptions extends EvaluatePermissionsOpts {
|
|
167
|
+
logger?: LoggerInstanceManager;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
declare const sdk: {
|
|
171
|
+
evaluatePermissions: ({ requiredPermissions, contextIds, logger, userId, options: { requireAll, permissionsEvaluationOperator, timeout, }, }: EvaluatePermissionsParams) => Promise<PermissionCheckResult>;
|
|
172
|
+
};
|
|
173
|
+
declare const middlewares: {
|
|
174
|
+
requirePermissions: (requiredPermissions: string[], options?: RequirePermissionsOptions) => (req: express.Request, res: express.Response, next: express.NextFunction) => Promise<void | express.Response<any, Record<string, any>>>;
|
|
175
|
+
};
|
|
176
|
+
declare const _default$1: {
|
|
177
|
+
sdk: {
|
|
178
|
+
evaluatePermissions: ({ requiredPermissions, contextIds, logger, userId, options: { requireAll, permissionsEvaluationOperator, timeout, }, }: EvaluatePermissionsParams) => Promise<PermissionCheckResult>;
|
|
179
|
+
};
|
|
180
|
+
middlewares: {
|
|
181
|
+
requirePermissions: (requiredPermissions: string[], options?: RequirePermissionsOptions) => (req: express.Request, res: express.Response, next: express.NextFunction) => Promise<void | express.Response<any, Record<string, any>>>;
|
|
182
|
+
};
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
declare const permissions_middlewares: typeof middlewares;
|
|
186
|
+
declare const permissions_sdk: typeof sdk;
|
|
187
|
+
declare namespace permissions {
|
|
188
|
+
export { _default$1 as default, permissions_middlewares as middlewares, permissions_sdk as sdk };
|
|
189
|
+
}
|
|
190
|
+
|
|
115
191
|
declare const getCurrentPayload: () => {
|
|
116
192
|
type: "httpRequest" | "webSocket" | "rabbit" | "bull";
|
|
117
|
-
readonly id:
|
|
193
|
+
readonly id: `${string}-${string}-${string}-${string}-${string}`;
|
|
118
194
|
readonly context: Map<string, unknown>;
|
|
119
195
|
readonly nonHeaderContext: Map<string, unknown>;
|
|
120
196
|
} | Record<string, never>;
|
|
@@ -132,7 +208,7 @@ declare const traceTypes: {
|
|
|
132
208
|
};
|
|
133
209
|
declare const newTrace: (type: "httpRequest" | "webSocket" | "rabbit" | "bull") => {
|
|
134
210
|
type: "httpRequest" | "webSocket" | "rabbit" | "bull";
|
|
135
|
-
readonly id:
|
|
211
|
+
readonly id: `${string}-${string}-${string}-${string}-${string}`;
|
|
136
212
|
readonly context: Map<string, unknown>;
|
|
137
213
|
readonly nonHeaderContext: Map<string, unknown>;
|
|
138
214
|
};
|
|
@@ -146,7 +222,7 @@ declare const _default: {
|
|
|
146
222
|
};
|
|
147
223
|
newTrace: (type: "httpRequest" | "webSocket" | "rabbit" | "bull") => {
|
|
148
224
|
type: "httpRequest" | "webSocket" | "rabbit" | "bull";
|
|
149
|
-
readonly id:
|
|
225
|
+
readonly id: `${string}-${string}-${string}-${string}-${string}`;
|
|
150
226
|
readonly context: Map<string, unknown>;
|
|
151
227
|
readonly nonHeaderContext: Map<string, unknown>;
|
|
152
228
|
};
|
|
@@ -160,7 +236,7 @@ declare const _default: {
|
|
|
160
236
|
eagerLoadPermissionsMiddleware: express.Handler;
|
|
161
237
|
getCurrentPayload: () => {
|
|
162
238
|
type: "httpRequest" | "webSocket" | "rabbit" | "bull";
|
|
163
|
-
readonly id:
|
|
239
|
+
readonly id: `${string}-${string}-${string}-${string}-${string}`;
|
|
164
240
|
readonly context: Map<string, unknown>;
|
|
165
241
|
readonly nonHeaderContext: Map<string, unknown>;
|
|
166
242
|
} | Record<string, never>;
|
|
@@ -187,6 +263,7 @@ declare const _default: {
|
|
|
187
263
|
} | undefined) => string | undefined;
|
|
188
264
|
CONTEXTS_IDS_HEADER: string;
|
|
189
265
|
authFromUserIdHeaderPlugin: fastify.FastifyPluginCallback<AuthFromUserIdHeaderOptions>;
|
|
266
|
+
permissions: typeof permissions;
|
|
190
267
|
};
|
|
191
268
|
|
|
192
|
-
export { AUTHORIZATION_METHODS, CONTEXTS_IDS_HEADER, UnauthorizedAccessError, ApiUser as User, type UserPayload, appMiddleware, authFromUserIdHeaderPlugin, checkBusinessModelPermission, checkDemandSourcePermission, checkFleetPermission, createOrSetRabbitTrace, _default as default, eagerLoadPermissionsMiddleware, enableTracing, getAuthorizationHeader, getCurrentPayload, getDecodedBearer, getRefreshTokenSecret, getTokenSecret, getUser, isUserExist, middleware, middlewareWithDecode, newTrace, traceTypes };
|
|
269
|
+
export { AUTHORIZATION_METHODS, CONTEXTS_IDS_HEADER, UnauthorizedAccessError, ApiUser as User, type UserPayload, appMiddleware, authFromUserIdHeaderPlugin, checkBusinessModelPermission, checkDemandSourcePermission, checkFleetPermission, createOrSetRabbitTrace, _default as default, eagerLoadPermissionsMiddleware, enableTracing, getAuthorizationHeader, getCurrentPayload, getDecodedBearer, getRefreshTokenSecret, getTokenSecret, getUser, isUserExist, middleware, middlewareWithDecode, newTrace, permissions, traceTypes };
|
package/lib/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import*as P from'@autofleet/outbreak';import {getCurrentContext,newTrace,traceTypes}from'@autofleet/outbreak';export{P as outbreak };import T from'jsonwebtoken';import xe from'node-cache';import $ from'object-hash';import v from'moment';import F from'@autofleet/network';var {DEPRECATED_JWT_SECRET:de,JWT_NEW_SECRET:ue,DEPRECATED_REFRESH_JWT_SECRET:pe,REFRESH_JWT_SECRET:me,DEPRECATION_UNIX_TIMESTAMP:fe}=process.env,L=(t,e,s)=>{let r=v(parseInt(fe,10)*1e3);try{let o;if(t){let{iat:i}=T.decode(t);o=v(i*1e3);}else o=v();return o.isBefore(r)?e:s}catch{return s}},le=t=>L(t,pe,me),_=t=>L(t,de,ue);var R=t=>t.replace("Bearer ",""),O=(t,e)=>{let s=R(t);return T.verify(s,_(s))};var Ee="00000000-0000-0000-0000-000000000000",Pe="ffffffff-ffff-ffff-ffff-ffffffffffff",h="[0-9a-f]",ge="[1-8]",he=new RegExp(`^(?:${h}{8}-${h}{4}-${ge}${h}{3}-[89ab]${h}{3}-${h}{12}|${Ee}|${Pe})$`,"i");function M(t){return typeof t=="string"&&he.test(t)}var B=10,j=process.env.API_GATEWAY_URL||"https://api.autofleet.io",w=new F({serviceName:"IDENTITY_MS",retries:3,retryCondition:()=>true,cache:process.env.NODE_ENV!=="test"?{maxAge:B*1e3}:void 0}),S=new F({baseURL:j,serviceUrl:j,retries:3,retryCondition:()=>true,cache:process.env.NODE_ENV!=="test"?{maxAge:B*1e3}:void 0});var l="x-af-elevated-permissions",y="x-af-context-ids",m=new xe({stdTTL:10}),J=(t,e)=>{let s={...t,fleets:{...t?.fleets},businessModels:{...t?.businessModels},demandSources:{...t?.demandSources}};for(let r of e)Object.keys(r).forEach(o=>{s[o]??={},Object.entries(r[o]).forEach(([i,n])=>{s[o][i]=(s[o][i]||[]).concat(n);});});return s};typeof Symbol.dispose!="symbol"&&Object.defineProperty(Symbol,"dispose",{__proto__:null,configurable:false,enumerable:false,value:Symbol.for("nodejs.dispose"),writable:false});typeof Symbol.asyncDispose!="symbol"&&Object.defineProperty(Symbol,"asyncDispose",{__proto__:null,configurable:false,enumerable:false,value:Symbol.for("nodejs.asyncDispose"),writable:false});var u=class{constructor(e,s,r,o){this.id=e;this.accountType=s;this.contextIds=o;this.privateElevatedPermissionsHash=new Map;this.appPermission={};this.emptyUser=!!e,r&&this.privateElevatedPermissionsHash.set(Symbol("initial"),r);}async getUserPermissions(){if(!this.id)return;if(this.privatePermissions)return this.privatePermissions;let e=$({id:this.id,contextIds:this.contextIds}),s=m.get(e);return s||({data:s}=await w.get(`/api/v1/users/${this.id}/authorization-payload`,{params:{contextIds:this.contextIds}}),m.set(e,s)),this.accountType=s.accountType,this.privatePermissions=s,this.privatePermissions}async useCustomPermissionLoader(e){if(!this.id)return;if(this.privatePermissions)return this.privatePermissions;let s=this.id,r=m.get(s);if(r)return this.privatePermissions=r,r;let o=await e(this.id);return m.set(s,o),this.privatePermissions=o,this.privatePermissions}get businessModels(){return this.getUserProperty("businessModels")}get fleets(){return this.getUserProperty("fleets")}get demandSources(){return this.getUserProperty("demandSources")}getUserProperty(e){if(!this.privatePermissions)throw new Error(`Cannot get ${e} without calling (async) getUserPermissions before`);return Object.keys(this.privatePermissions[e]||{})}get elevatedPermissions(){return J(void 0,this.privateElevatedPermissionsHash.values())}get permissions(){if(!this.privatePermissions)throw new Error("Cannot get permissions without calling (async) getUserPermissions before");return J(this.privatePermissions,this.privateElevatedPermissionsHash.values())}elevatePermissions(e){let s=Symbol();Object.values(e).forEach(c=>{Object.keys(c).forEach(a=>{if(!M(a))throw new Error(`Entity id on elevatePermissions is not a valid UUID, provided: ${a}`)});});let r=getCurrentContext();if(!r)throw new Error("Cannot find current user cross services trace");let o=JSON.parse(r.context[l]||"{}"),i=Object.assign(o,e);this.privateElevatedPermissionsHash.set(s,i),r.context.set(l,JSON.stringify(this.elevatedPermissions));let n=()=>{this.privateElevatedPermissionsHash.delete(s),r.context.set(l,JSON.stringify(this.elevatedPermissions));};return n[Symbol.dispose]=n,n}async getUserPermissionsLegacy(){if(!this.id)return;if(this.privatePermissionsLegacy)return this.privatePermissionsLegacy;let e=$({id:this.id,contextIds:this.contextIds,legacy:true}),s=m.get(e);return s||({data:s}=await w.get(`/api/v1/users/${this.id}/authorization-payload-legacy`,{params:{contextIds:this.contextIds}}),m.set(e,s)),this.privatePermissionsLegacy=s,this.privatePermissionsLegacy}get permissionsLegacy(){if(!this.privatePermissionsLegacy)throw new Error("Cannot get permissionsLegacy without calling (async) getUserPermissionsLegacy before");return this.privatePermissionsLegacy}async getUserAppPermissions(e,s){if(!this.id||!e||!s)return;let r=this.appPermission[e];if(r)return r;let o=`${this.id}:${e}`,i=m.get(o);if(i)return this.appPermission[e]=i,i;let{data:n}=await S.post(`/api/v1/apps/${e}/get-user-payload`,{userId:this.id},{headers:{"x-autofleet-apps-secret":s}});return m.set(o,n),this.appPermission[e]=n,this.appPermission[e]}};var W=async(t,e)=>{let{data:s}=await S.post("/api/v1/auth",{bearer:t,appId:e});return s};var E=class extends Error{constructor(){super(...arguments);this.name="AppDoesNotExist";this.message="app does not exist";}};var G="identity-ms",X="accessToken",f="userObject",x="x-af-user-id",H="X-IAF-ORIGIN-SERVICE",A="x-af-user-permissions",z=H.toLowerCase(),V="x-autofleet-apps-secret";var b=async(t,e)=>{let s=e[H]||e[z]||"";if(!Array.isArray(s)&&s.toLowerCase()===G)return;let{eagerLoadUserPermissions:r,eagerLoadUserPermissionsLegacy:o,customPermissionLoader:i}=t,n=e[x];if(!n||Array.isArray(n))return;let c=e[l]?.length>0?JSON.parse(e[l]):{},a=e?.[y]?.split(","),d=new u(n,"user",c,a);return r&&(i?await d.useCustomPermissionLoader(i):await d.getUserPermissions()),o&&await d.getUserPermissionsLegacy(),getCurrentContext().nonHeaderContext?.set(f,d),d};var Y=(t={})=>async(e,s,r)=>{try{let o=await b(t,e.headers);o&&(e.user=o,e.headers[A]=o),r();}catch{s.status(401).json({error:"cannot authenticate user"});}},Z=(t={})=>async(e,s,r)=>{let{eagerLoadUserPermissions:o,eagerLoadUserPermissionsLegacy:i,returnErrorIfNoToken:n}=t,c;if(e.headers.authorization){try{c=await O(e.headers.authorization);}catch(g){g instanceof T.TokenExpiredError?s.status(401).json({errors:["Access token expired"]}):g instanceof T.JsonWebTokenError?s.status(400).json({errors:[g.message]}):s.status(500).json({errors:["Server error while parsing token"]});return}let a=c?.user?.id;a&&(e.headers[x]=a);let d=e.headers?.[y]?.split(","),p=new u(a,c?.user?.accountType,void 0,d);(o||i)&&await Promise.all([o&&p.getUserPermissions(),i&&p.getUserPermissionsLegacy()]),e.user=p,getCurrentContext().nonHeaderContext?.set(f,p),e.headers[A]=p;}else if(n){s.status(401).json({errors:["No token provided"]});return}r();},Q=t=>async(e,s,r)=>{let{appId:o,clientSecret:i}=t,n;if(!e.headers.authorization){s.status(401).json({errors:["No token provided"]});return}try{if(n=await W(e.headers.authorization,o),!n)throw new E}catch(p){if(p instanceof T.TokenExpiredError){s.status(401).json({errors:["Access token expired"]});return}if([T.JsonWebTokenError,E].some(g=>p instanceof g)){s.status(400).json({errors:[p.message]});return}s.status(500).json({errors:["Server error while parsing token"]});return}let c=n?.userId;c&&(e.headers[x]=c);let a=new u(c);o&&(e.headers[V]=i,await a.getUserAppPermissions(o,i)),e.user=a;let d=getCurrentContext().nonHeaderContext;d?.set(f,a),d?.set(X,R(e.headers.authorization)),e.headers[A]=a,r();},q=async(t,e,s)=>{await t.user.getUserPermissions(),s();},ee=t=>t.headers.authorization?O(t.headers.authorization):null,te=async(t,e)=>{let s=new u(e);await s.getUserPermissions(),t??=newTrace(traceTypes.RABBIT),t.nonHeaderContext.set(f,s);},se=u;var N=(t,e,s)=>{t.decorateRequest("user",void 0),t.addHook("onRequest",async(r,o)=>{try{let i=await b(e,r.headers);i&&(r.user=i);}catch{o.status(401).send({error:"cannot authenticate user"});}}),s();};N[Symbol.for("skip-override")]=true;var I=()=>getCurrentContext().nonHeaderContext?.get(f),D=()=>I()?.id,k=(t,e)=>!D()||Object.hasOwn(I().permissions[e],t),re=t=>k(t,"fleets"),oe=t=>k(t,"businessModels"),ie=t=>k(t,"demandSources");var C=class extends Error{constructor(s=null,r="UnauthorizedAccessError"){super(r);this.user=s;this.name="UnauthorizedAccessError";}};var U={NONE:"NONE",BASIC:"BASIC",JWT:"JWT"},ne={[U.NONE]:()=>{},[U.BASIC]:t=>{let{username:e,password:s}=t;return `Basic ${Buffer.from(`${e}:${s}`).toString("base64")}`},[U.JWT]:t=>{let{secret:e}=t;if(e)return `Bearer ${T.sign({},e,{expiresIn:10})}`}},ae=t=>{let e=t?.method;if(!(!e||!ne[e]))return ne[e](t)};var Ce=P.getCurrentContext,bt=({outbreakOptions:t={},logger:e}={})=>{P.default({headersPrefix:"x-af",contextMiddlewareGetter:e?.addContextMiddleware,...t});},{traceTypes:ve,newTrace:_e}=P;var Tt={traceTypes:ve,newTrace:_e,User:se,middleware:Y,middlewareWithDecode:Z,eagerLoadPermissionsMiddleware:q,getCurrentPayload:Ce,getDecodedBearer:ee,checkFleetPermission:re,checkBusinessModelPermission:oe,checkDemandSourcePermission:ie,isUserExist:D,getUser:I,UnauthorizedAccessError:C,appMiddleware:Q,createOrSetRabbitTrace:te,outbreak:P,AUTHORIZATION_METHODS:U,getAuthorizationHeader:ae,CONTEXTS_IDS_HEADER:y,authFromUserIdHeaderPlugin:N};
|
|
2
|
-
export{
|
|
1
|
+
import*as I from'@autofleet/outbreak';import {getCurrentContext,newTrace,traceTypes}from'@autofleet/outbreak';export{I as outbreak };import N from'jsonwebtoken';import Me from'node-cache';import Q from'object-hash';import D from'moment';import X from'@autofleet/network';var Ue=Object.defineProperty;var xe=(t,e)=>{for(var s in e)Ue(t,s,{get:e[s],enumerable:true});};var {DEPRECATED_JWT_SECRET:Ae,JWT_NEW_SECRET:Te,DEPRECATED_REFRESH_JWT_SECRET:_e,REFRESH_JWT_SECRET:Ce,DEPRECATION_UNIX_TIMESTAMP:Ne}=process.env,J=(t,e,s)=>{let r=D(parseInt(Ne,10)*1e3);try{let o;if(t){let{iat:i}=N.decode(t);o=D(i*1e3);}else o=D();return o.isBefore(r)?e:s}catch{return s}},be=t=>J(t,_e,Ce),k=t=>J(t,Ae,Te);var L=t=>t.replace("Bearer ",""),H=(t,e)=>{let s=L(t);return N.verify(s,k(s))};var De="00000000-0000-0000-0000-000000000000",ke="ffffffff-ffff-ffff-ffff-ffffffffffff",S="[0-9a-f]",Le="[1-8]",He=new RegExp(`^(?:${S}{8}-${S}{4}-${Le}${S}{3}-[89ab]${S}{3}-${S}{12}|${De}|${ke})$`,"i");function V(t){return typeof t=="string"&&He.test(t)}var K=10,G=process.env.API_GATEWAY_URL||"https://api.autofleet.io",O=new X({serviceName:"IDENTITY_MS",retries:3,retryCondition:()=>true,cache:process.env.NODE_ENV!=="test"?{maxAge:K*1e3}:void 0}),T=new X({baseURL:G,serviceUrl:G,retries:3,retryCondition:()=>true,cache:process.env.NODE_ENV!=="test"?{maxAge:K*1e3}:void 0});var h="x-af-elevated-permissions",f="x-af-context-ids",E=new Me({stdTTL:10}),Y=(t,e)=>{let s={...t,fleets:{...t?.fleets},businessModels:{...t?.businessModels},demandSources:{...t?.demandSources}};for(let r of e)Object.keys(r).forEach(o=>{s[o]??={},Object.entries(r[o]).forEach(([i,n])=>{s[o][i]=(s[o][i]||[]).concat(n);});});return s};typeof Symbol.dispose!="symbol"&&Object.defineProperty(Symbol,"dispose",{__proto__:null,configurable:false,enumerable:false,value:Symbol.for("nodejs.dispose"),writable:false});typeof Symbol.asyncDispose!="symbol"&&Object.defineProperty(Symbol,"asyncDispose",{__proto__:null,configurable:false,enumerable:false,value:Symbol.for("nodejs.asyncDispose"),writable:false});var p=class{constructor(e,s,r,o){this.id=e;this.accountType=s;this.contextIds=o;this.privateElevatedPermissionsHash=new Map;this.appPermission={};this.emptyUser=!!e,r&&this.privateElevatedPermissionsHash.set(Symbol("initial"),r);}async getUserPermissions(){if(!this.id)return;if(this.privatePermissions)return this.privatePermissions;let e=Q({id:this.id,contextIds:this.contextIds}),s=E.get(e);return s||({data:s}=await O.get(`/api/v1/users/${this.id}/authorization-payload`,{params:{contextIds:this.contextIds}}),E.set(e,s)),this.accountType=s.accountType,this.privatePermissions=s,this.privatePermissions}async useCustomPermissionLoader(e){if(!this.id)return;if(this.privatePermissions)return this.privatePermissions;let s=this.id,r=E.get(s);if(r)return this.privatePermissions=r,r;let o=await e(this.id);return E.set(s,o),this.privatePermissions=o,this.privatePermissions}get businessModels(){return this.getUserProperty("businessModels")}get fleets(){return this.getUserProperty("fleets")}get demandSources(){return this.getUserProperty("demandSources")}getUserProperty(e){if(!this.privatePermissions)throw new Error(`Cannot get ${e} without calling (async) getUserPermissions before`);return Object.keys(this.privatePermissions[e]||{})}get elevatedPermissions(){return Y(void 0,this.privateElevatedPermissionsHash.values())}get permissions(){if(!this.privatePermissions)throw new Error("Cannot get permissions without calling (async) getUserPermissions before");return Y(this.privatePermissions,this.privateElevatedPermissionsHash.values())}elevatePermissions(e){let s=Symbol();Object.values(e).forEach(c=>{Object.keys(c).forEach(a=>{if(!V(a))throw new Error(`Entity id on elevatePermissions is not a valid UUID, provided: ${a}`)});});let r=getCurrentContext();if(!r)throw new Error("Cannot find current user cross services trace");let o=JSON.parse(r.context[h]||"{}"),i=Object.assign(o,e);this.privateElevatedPermissionsHash.set(s,i),r.context.set(h,JSON.stringify(this.elevatedPermissions));let n=()=>{this.privateElevatedPermissionsHash.delete(s),r.context.set(h,JSON.stringify(this.elevatedPermissions));};return n[Symbol.dispose]=n,n}async getUserPermissionsLegacy(){if(!this.id)return;if(this.privatePermissionsLegacy)return this.privatePermissionsLegacy;let e=Q({id:this.id,contextIds:this.contextIds,legacy:true}),s=E.get(e);return s||({data:s}=await O.get(`/api/v1/users/${this.id}/authorization-payload-legacy`,{params:{contextIds:this.contextIds}}),E.set(e,s)),this.privatePermissionsLegacy=s,this.privatePermissionsLegacy}get permissionsLegacy(){if(!this.privatePermissionsLegacy)throw new Error("Cannot get permissionsLegacy without calling (async) getUserPermissionsLegacy before");return this.privatePermissionsLegacy}async getUserAppPermissions(e,s){if(!this.id||!e||!s)return;let r=this.appPermission[e];if(r)return r;let o=`${this.id}:${e}`,i=E.get(o);if(i)return this.appPermission[e]=i,i;let{data:n}=await T.post(`/api/v1/apps/${e}/get-user-payload`,{userId:this.id},{headers:{"x-autofleet-apps-secret":s}});return E.set(o,n),this.appPermission[e]=n,this.appPermission[e]}};var Z=async(t,e)=>{let{data:s}=await T.post("/api/v1/auth",{bearer:t,appId:e});return s};var R=class extends Error{constructor(){super(...arguments);this.name="AppDoesNotExist";this.message="app does not exist";}};var q="identity-ms",ee="accessToken",P="userObject",U="x-af-user-id",M="X-IAF-ORIGIN-SERVICE",_="x-af-user-permissions",se=M.toLowerCase(),te="x-autofleet-apps-secret";var C=async(t,e)=>{let s=e[M]||e[se]||"";if(!Array.isArray(s)&&s.toLowerCase()===q)return;let{eagerLoadUserPermissions:r,eagerLoadUserPermissionsLegacy:o,customPermissionLoader:i}=t,n=e[U];if(!n||Array.isArray(n))return;let c=e[h]?.length>0?JSON.parse(e[h]):{},a=e?.[f]?.split(","),m=new p(n,"user",c,a);return r&&(i?await m.useCustomPermissionLoader(i):await m.getUserPermissions()),o&&await m.getUserPermissionsLegacy(),getCurrentContext().nonHeaderContext?.set(P,m),m};var oe=(t={})=>async(e,s,r)=>{try{let o=await C(t,e.headers);o&&(e.user=o,e.headers[_]=o),r();}catch{s.status(401).json({error:"cannot authenticate user"});}},ie=(t={})=>async(e,s,r)=>{let{eagerLoadUserPermissions:o,eagerLoadUserPermissionsLegacy:i,returnErrorIfNoToken:n}=t,c;if(e.headers.authorization){try{c=await H(e.headers.authorization);}catch(d){d instanceof N.TokenExpiredError?s.status(401).json({errors:["Access token expired"]}):d instanceof N.JsonWebTokenError?s.status(400).json({errors:[d.message]}):s.status(500).json({errors:["Server error while parsing token"]});return}let a=c?.user?.id;a&&(e.headers[U]=a);let m=e.headers?.[f]?.split(","),u=new p(a,c?.user?.accountType,void 0,m);(o||i)&&await Promise.all([o&&u.getUserPermissions(),i&&u.getUserPermissionsLegacy()]),e.user=u,getCurrentContext().nonHeaderContext?.set(P,u),e.headers[_]=u;}else if(n){s.status(401).json({errors:["No token provided"]});return}r();},ne=t=>async(e,s,r)=>{let{appId:o,clientSecret:i}=t,n;if(!e.headers.authorization){s.status(401).json({errors:["No token provided"]});return}try{if(n=await Z(e.headers.authorization,o),!n)throw new R}catch(u){if(u instanceof N.TokenExpiredError){s.status(401).json({errors:["Access token expired"]});return}if([N.JsonWebTokenError,R].some(d=>u instanceof d)){s.status(400).json({errors:[u.message]});return}s.status(500).json({errors:["Server error while parsing token"]});return}let c=n?.userId;c&&(e.headers[U]=c);let a=new p(c);o&&(e.headers[te]=i,await a.getUserAppPermissions(o,i)),e.user=a;let m=getCurrentContext().nonHeaderContext;m?.set(P,a),m?.set(ee,L(e.headers.authorization)),e.headers[_]=a,r();},ae=async(t,e,s)=>{await t.user.getUserPermissions(),s();},ce=t=>t.headers.authorization?H(t.headers.authorization):null,ue=async(t,e)=>{let s=new p(e);await s.getUserPermissions(),t??=newTrace(traceTypes.RABBIT),t.nonHeaderContext.set(P,s);},me=p;var F=(t,e,s)=>{t.decorateRequest("user",void 0),t.addHook("onRequest",async(r,o)=>{try{let i=await C(e,r.headers);i&&(r.user=i);}catch{o.status(401).send({error:"cannot authenticate user"});}}),s();};F[Symbol.for("skip-override")]=true;var g=()=>getCurrentContext().nonHeaderContext?.get(P),B=()=>g()?.id,j=(t,e)=>!B()||Object.hasOwn(g().permissions[e],t),de=t=>j(t,"fleets"),pe=t=>j(t,"businessModels"),le=t=>j(t,"demandSources");var b=class extends Error{constructor(s=null,r="UnauthorizedAccessError"){super(r);this.user=s;this.name="UnauthorizedAccessError";}};var x={NONE:"NONE",BASIC:"BASIC",JWT:"JWT"},Ee={[x.NONE]:()=>{},[x.BASIC]:t=>{let{username:e,password:s}=t;return `Basic ${Buffer.from(`${e}:${s}`).toString("base64")}`},[x.JWT]:t=>{let{secret:e}=t;if(e)return `Bearer ${N.sign({},e,{expiresIn:10})}`}},fe=t=>{let e=t?.method;if(!(!e||!Ee[e]))return Ee[e](t)};var z={};xe(z,{default:()=>rs,middlewares:()=>Re,sdk:()=>he});var $=class{constructor(e){this.cache=e||new Me({stdTTL:10});}async getUserPermissions(e,s){try{let r=o=>`perm-${e}-${o}`;return await this.cache.mget(s.map(r))}catch{return {}}}async setUserPermissions(e,s,r){try{let o=n=>`perm-${e}-${n}`,i=Object.entries(s).map(([n,c])=>({key:o(n),val:c,ttl:r??10}));return await this.cache.mset(i),{success:!0}}catch{return {success:false}}}async getSeenPermissions(e,s,r){try{let o=r.sort().join(","),i=n=>`seen-${e}-${n}-${o}`;return await this.cache.mget(s.map(i))}catch{return {}}}async setSeenPermissions(e,s,r,o){try{let i=r.sort().join(","),n=a=>`seen-${e}-${a}-${i}`,c=s.map(a=>({key:n(a),val:!0,ttl:o??10}));return await this.cache.mset(c),{success:!0}}catch{return {success:false}}}},v=new $;var y={AND:"and",OR:"or"},l={USER_NOT_FOUND:"USER_NOT_FOUND",INSUFFICIENT_PERMISSIONS:"INSUFFICIENT_PERMISSIONS",VALIDATION_ERROR:"VALIDATION_ERROR",API_ERROR:"API_ERROR",NO_REQUIRED_PERMISSIONS:"NO_REQUIRED_PERMISSIONS",UNAUTHORIZED:"UNAUTHORIZED",BAD_REQUEST:"BAD_REQUEST",INTERNAL_ERROR:"INTERNAL_ERROR"},A={USER_NOT_FOUND:"User not found",INSUFFICIENT_PERMISSIONS:"User does not have sufficient permissions",VALIDATION_ERROR:"Validation error occurred",API_ERROR:"API error occurred",NO_REQUIRED_PERMISSIONS:"No required permissions provided for evaluation",UNAUTHORIZED:"User is not authorized to perform this action",BAD_REQUEST:"Bad request, please check the input parameters",INTERNAL_ERROR:"Internal server error occurred while checking permissions"};var ge=(t,e,s)=>{let r=new Set(t),o=e.filter(i=>r.has(i));return s===y.AND?o.length===e.length:o.length>0};var Ve=(t,e)=>{let s=Object.values(t);return e?s.every(r=>r.hasRequiredPermissions):s.some(r=>r.hasRequiredPermissions)};var Ge=t=>{let e=[];return t?.length||e.push("contextIds cannot be empty"),e},Pe=(t,e,s,r)=>({isAuthorized:false,error:t,resolvedPermissions:{},requiredPermissions:e,contextIds:s,...r&&{message:r}}),Xe=async(t,e,s)=>{let r={},o=[];Object.entries(e).forEach(([i,n])=>{n?.permissions&&(n.hasRequiredPermissions?r[i]=n.permissions:o.push(i));}),Object.keys(r).length>0&&await v.setUserPermissions(t,r),o.length>0&&await v.setSeenPermissions(t,o,s);},Ke=async(t,e,s)=>{let r=await v.getSeenPermissions(t,e,s);return e.filter(o=>!r[`seen-${t}-${o}-${s.sort().join(",")}`])},Qe=(t,e)=>{let s=t.filter(o=>!e.includes(o)),r={};return s.forEach(o=>{r[o]={permissions:[],hasRequiredPermissions:false};}),r},Ye=(t,e,s)=>{let r={};return Object.keys(t||{}).length&&Object.entries(t).forEach(([o,i])=>{let n=ge(i,e,s);r[o]={permissions:i,hasRequiredPermissions:n};}),r},Ze=async(t,e,s,r)=>{let o=await O.post("/api/v1/permissions/resolve",{userId:t,contextIds:e,requiredPermissions:s},{timeout:r.timeout}),{data:i}=o;if(!Object.keys(i||{}).length)throw new Error("Failed to resolve permissions");if(r.permissionsEvaluationOperator===y.AND)return i;let n={};return Object.entries(i).forEach(([c,a])=>{let m=a?.permissions||[],u=ge(m,s,r.permissionsEvaluationOperator);n[c]={permissions:m,hasRequiredPermissions:u};}),n},qe=(t,e,s,r)=>{let o=Ge(t);return o.length?Pe(l.VALIDATION_ERROR,e,t,o.join(", ")):s?e?.length?null:(r?.info("No requiredPermissions provided",{userId:s,contextIds:t}),{isAuthorized:false,userId:s,resolvedPermissions:{},requiredPermissions:e,contextIds:t,error:l.NO_REQUIRED_PERMISSIONS}):(r?.warn("User not found in context, cannot check permissions",{contextIds:t,requiredPermissions:e}),Pe(l.USER_NOT_FOUND,e,t))},es=async(t,e,s,r)=>{let o=await v.getUserPermissions(t,e),i=Ye(o,s,r.permissionsEvaluationOperator),n={...i},c=e.filter(u=>!i[u]),a=await Ke(t,c,s),m=Qe(c,a);if(n={...n,...m},a.length){let u=await Ze(t,a,s,r);n={...n,...u},await Xe(t,u,s);}return n},w=async({requiredPermissions:t,contextIds:e,logger:s,userId:r,options:{requireAll:o=true,permissionsEvaluationOperator:i=y.AND,timeout:n=1e4}})=>{let c=r||g()?.id||null,a=qe(e,t,c,s);if(a)return a;let m=await es(c,e,t,{permissionsEvaluationOperator:i,timeout:n}),u=Ve(m,o);return s?.info("Resolved permissions",{userId:c,requiredPermissions:t,isAuthorized:u,requireAll:o,permissionsEvaluationOperator:i,contextIds:e}),{isAuthorized:u,userId:c,resolvedPermissions:m,requiredPermissions:t,contextIds:e,...u?{}:{error:l.INSUFFICIENT_PERMISSIONS}}};var ss=t=>{let e=t.headers?.[f]?.split(",")||[],s=t.query?.contextIds?.split(",")||[],r=t.body?.contextIds||[];return Array.from(new Set([...e,...s,...r])).filter(Boolean)},ts=(t,e,s,r,o,i,n,c,a)=>r?(c?.error(e,{url:i.url,method:i.method,requiredPermissions:a?.requiredPermissions||[],...a}),o.status(s).json({error:t,message:e,...a?.requiredPermissions&&{requiredPermissions:a.requiredPermissions}})):(c?.warn(e,{url:i.url,method:i.method,requiredPermissions:a?.requiredPermissions||[],...a}),n()),ye=(t,e={enforce:false,requireAll:true,permissionsEvaluationOperator:y.AND})=>async(s,r,o)=>{try{let{logger:i,enforce:n,requireAll:c,permissionsEvaluationOperator:a}=e,m=(Ie,Se,Oe)=>ts(Ie,Se,Oe,n,r,s,o,i,{requiredPermissions:t}),u=g();if(!u?.id)return m(l.UNAUTHORIZED,A.UNAUTHORIZED,401);let d=ss(s);if(!d?.length)return m(l.BAD_REQUEST,A.BAD_REQUEST,400);let W=await w({requiredPermissions:t,contextIds:d,logger:i,userId:u.id,options:{requireAll:c??!0,permissionsEvaluationOperator:a??y.AND,timeout:1e4}});return W.isAuthorized?(i?.info("User has required permissions",{userId:u.id,requiredPermissions:t,contextIds:d,url:s.url,method:s.method}),o()):n?r.status(403).json({error:l.INSUFFICIENT_PERMISSIONS,message:A.INSUFFICIENT_PERMISSIONS,required:t,contexts:d,userId:W.userId}):(i?.warn("User does not have required permissions, skipping enforcement",{userId:u.id,requiredPermissions:t,contextIds:d,url:s.url,method:s.method}),o())}catch(i){return e.logger?.error("Error in requirePermissions middleware",{error:i,requiredPermissions:t,url:s.url,method:s.method}),e.enforce?r.status(500).json({error:l.INTERNAL_ERROR,message:A.INTERNAL_ERROR}):(e.logger?.error("Error during permission check, skipping enforcement",{error:i,url:s.url,method:s.method}),o())}};var he={evaluatePermissions:w},Re={requirePermissions:ye},rs={sdk:he,middlewares:Re};var os=I.getCurrentContext,gt=({outbreakOptions:t={},logger:e}={})=>{I.default({headersPrefix:"x-af",contextMiddlewareGetter:e?.addContextMiddleware,...t});},{traceTypes:is,newTrace:ns}=I;var yt={traceTypes:is,newTrace:ns,User:me,middleware:oe,middlewareWithDecode:ie,eagerLoadPermissionsMiddleware:ae,getCurrentPayload:os,getDecodedBearer:ce,checkFleetPermission:de,checkBusinessModelPermission:pe,checkDemandSourcePermission:le,isUserExist:B,getUser:g,UnauthorizedAccessError:b,appMiddleware:ne,createOrSetRabbitTrace:ue,outbreak:I,AUTHORIZATION_METHODS:x,getAuthorizationHeader:fe,CONTEXTS_IDS_HEADER:f,authFromUserIdHeaderPlugin:F,permissions:z};
|
|
2
|
+
export{x as AUTHORIZATION_METHODS,f as CONTEXTS_IDS_HEADER,b as UnauthorizedAccessError,me as User,ne as appMiddleware,F as authFromUserIdHeaderPlugin,pe as checkBusinessModelPermission,le as checkDemandSourcePermission,de as checkFleetPermission,ue as createOrSetRabbitTrace,yt as default,ae as eagerLoadPermissionsMiddleware,gt as enableTracing,fe as getAuthorizationHeader,os as getCurrentPayload,ce as getDecodedBearer,be as getRefreshTokenSecret,k as getTokenSecret,g as getUser,B as isUserExist,oe as middleware,ie as middlewareWithDecode,ns as newTrace,z as permissions,is as traceTypes};//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/secret-getter.ts","../src/utils.ts","../src/services.ts","../src/user/ApiUser.ts","../src/app-auth.ts","../src/exceptions/appDoesNotExist.ts","../src/user/const.ts","../src/user/common.ts","../src/user/index.ts","../src/user/fastify.ts","../src/check-permission.ts","../src/errors.ts","../src/authorization.ts","../src/index.ts"],"names":["DEPRECATED_JWT_SECRET","JWT_NEW_SECRET","DEPRECATED_REFRESH_JWT_SECRET","REFRESH_JWT_SECRET","DEPRECATION_UNIX_TIMESTAMP","getRelevantSecret","token","deprecatedSecret","newSecret","deprecationTime","moment","unixTime","iat","jwt","getRefreshTokenSecret","getTokenSecret","getAuthFromBearer","bearer","decodeBearer","appSecret","EMPTY_UUID","FULL_UUID","VALID_CHARS_REGEX","UUID_VERSION_REGEX","UUID_REGEX","validateUUID","uuid","CACHE_LIFETIME_IN_SEC","apiGwUrl","IdentityNetwork","Network","AutofleetApiNetwork","ELEVATED_PERMISSIONS_HEADER","CONTEXTS_IDS_HEADER","userCache","NodeCache","mergePermissions","target","sources","permissions","source","entityType","entityId","perms","ApiUser","id","accountType","elevatedPermissions","contextIds","cacheKey","objectHash","data","customPermissionLoader","cachedResult","key","addedPermissions","elevationId","entityIds","currentUserTrace","getCurrentContext","currentElevation","newElevation","cleanup","appId","clientSecret","currentAppPermission","decodeAppBearer","decoded","AppDoesNotExist","IDENTITY_MS","ACCESS_TOKEN","USER_OBJECT","USER_TRACING_HEADER","ORIGIN_HEADER","USER_PERMISSIONS_HEADER","LOWER_CASE_ORIGIN_HEADER","AUTOFLEET_APPS_SECRET_HEADER","authFromUserIdHeader","options","headers","originHeader","eagerLoadUserPermissions","eagerLoadUserPermissionsLegacy","userId","elevatedPermissionsFromHeader","userObject","middleware","req","res","next","middlewareWithDecode","returnErrorIfNoToken","e","appMiddleware","Err","currentTraceContext","eagerLoadPermissionsMiddleware","getDecodedBearer","createOrSetRabbitTrace","trace","newTrace","traceTypes","user_default","authFromUserIdHeaderPlugin","fastify","done","request","reply","user","getUser","isUserExist","checkUserPermissions","checkFleetPermission","fleetId","checkBusinessModelPermission","businessModelId","checkDemandSourcePermission","demandSourceId","UnauthorizedAccessError","message","AUTHORIZATION_METHODS","AUTHORIZATION_ACTIONS","authorizationSettings","username","password","secret","getAuthorizationHeader","authorizationMethod","getCurrentPayload","enableTracing","outbreakOptions","logger","outbreak","index_default"],"mappings":"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","file":"index.js","sourcesContent":["import jwt from 'jsonwebtoken';\nimport moment from 'moment';\n\nconst {\n DEPRECATED_JWT_SECRET, JWT_NEW_SECRET,\n DEPRECATED_REFRESH_JWT_SECRET, REFRESH_JWT_SECRET,\n DEPRECATION_UNIX_TIMESTAMP,\n} = process.env;\n\nconst getRelevantSecret = (token: string | undefined, deprecatedSecret: string, newSecret: string): string => {\n const deprecationTime = moment(parseInt(DEPRECATION_UNIX_TIMESTAMP, 10) * 1000);\n try {\n let unixTime: moment.Moment;\n if (token) {\n const { iat } = jwt.decode(token) as jwt.JwtPayload;\n unixTime = moment(iat * 1000);\n } else {\n unixTime = moment();\n }\n return unixTime.isBefore(deprecationTime) ? deprecatedSecret : newSecret;\n } catch (e) {\n return newSecret;\n }\n};\n\nexport const getRefreshTokenSecret = (token?: string): string => getRelevantSecret(token, DEPRECATED_REFRESH_JWT_SECRET, REFRESH_JWT_SECRET);\nexport const getTokenSecret = (token?: string): string => getRelevantSecret(token, DEPRECATED_JWT_SECRET, JWT_NEW_SECRET);\n","import type { UUID } from 'node:crypto';\nimport jwt from 'jsonwebtoken';\nimport { getTokenSecret } from './secret-getter';\n\ntype Context = Partial<Record<ContextProp | 'id', string>> & { subSystem?: SubSystemType; permissions?: string[]; entityId: string; };\n\nconst CONTEXT_PROPS = ['fleetId', 'businessModelId', 'demandSourceId'] as const;\ntype ContextProp = typeof CONTEXT_PROPS[number];\nconst CONTEXT_MAP_PROPS = {\n fleet: 'fleets',\n business: 'businessModels',\n demand: 'demandSources',\n} as const;\ntype SubSystemType = keyof typeof CONTEXT_MAP_PROPS;\ntype ContextSubSystemProp = typeof CONTEXT_MAP_PROPS[SubSystemType];\n\nexport const getAuthFromBearer = (bearer: string): string => bearer.replace('Bearer ', '');\n\nexport const decodeBearer = (bearer: string, appSecret?: string): any => {\n const token = getAuthFromBearer(bearer);\n const decoded = jwt.verify(token, appSecret || getTokenSecret(token));\n return decoded;\n};\n\nexport const parsePermissions = (contextId: string, decodedToken: { contexts: Context[]; }): { key: string; value: string; } | undefined => {\n if (!decodedToken) return undefined;\n const { contexts } = decodedToken;\n const activeContext = contexts.find((context) => context.id === contextId);\n\n const permissionsValue = `${activeContext.permissions?.map((cp) => `${cp},`)}`;\n\n return {\n key: activeContext.entityId,\n value: permissionsValue,\n };\n};\n\ntype EntitiesFromContext = { [key in ContextSubSystemProp]?: Record<string, string> };\nexport const getEntitiesFromContext = (contextId: string | undefined, decodedToken: { contexts: Context[]; }): EntitiesFromContext => {\n if (!decodedToken) return {};\n let { contexts } = decodedToken;\n if (contextId) {\n contexts = contexts.filter((context) => context.id === contextId);\n }\n\n const attributes: EntitiesFromContext = {};\n contexts.forEach((context) => {\n const prop = CONTEXT_MAP_PROPS[context.subSystem || 'business'];\n\n const permissions = parsePermissions(context.id, decodedToken);\n if (!permissions) return;\n attributes[prop] ||= {};\n attributes[prop][permissions.key] = permissions.value;\n });\n\n return attributes;\n};\n\ntype ContextAttributes = { [key in ContextProp]?: string[] };\nexport const getContextAttributes = (contextId: string | undefined, decodedToken: { contexts: Context[]; }): ContextAttributes => {\n if (!decodedToken) return {};\n let { contexts } = decodedToken;\n if (contextId) {\n contexts = contexts.filter((context) => context.id === contextId);\n }\n const attributes: ContextAttributes = {};\n contexts.forEach((context) => {\n CONTEXT_PROPS.forEach((prop) => {\n if (context[prop]) {\n attributes[prop] ||= [];\n attributes[prop].push(context[prop]);\n }\n });\n });\n return attributes;\n};\n\nconst EMPTY_UUID = '00000000-0000-0000-0000-000000000000';\nconst FULL_UUID = 'ffffffff-ffff-ffff-ffff-ffffffffffff';\nconst VALID_CHARS_REGEX = '[0-9a-f]';\nconst UUID_VERSION_REGEX = '[1-8]';\nconst UUID_REGEX = new RegExp(\n `^(?:${VALID_CHARS_REGEX}{8}-${VALID_CHARS_REGEX}{4}-${UUID_VERSION_REGEX}${VALID_CHARS_REGEX}{3}-[89ab]${VALID_CHARS_REGEX}{3}-${VALID_CHARS_REGEX}{12}|${EMPTY_UUID}|${FULL_UUID})$`,\n 'i',\n);\nexport function validateUUID(uuid: unknown): uuid is UUID {\n return typeof uuid === 'string' && UUID_REGEX.test(uuid);\n}\n","import Network from '@autofleet/network';\n\nconst CACHE_LIFETIME_IN_SEC = 10;\nconst apiGwUrl = process.env.API_GATEWAY_URL || 'https://api.autofleet.io';\n\n// eslint-disable-next-line import/prefer-default-export\nexport const IdentityNetwork = new Network({\n serviceName: 'IDENTITY_MS',\n retries: 3,\n retryCondition: () => true,\n cache: process.env.NODE_ENV !== 'test' ? {\n maxAge: CACHE_LIFETIME_IN_SEC * 1000,\n } : undefined,\n});\n\nexport const AutofleetApiNetwork = new Network({\n baseURL: apiGwUrl,\n serviceUrl: apiGwUrl,\n retries: 3,\n retryCondition: () => true,\n cache: process.env.NODE_ENV !== 'test' ? {\n maxAge: CACHE_LIFETIME_IN_SEC * 1000,\n } : undefined,\n});\n","import NodeCache from 'node-cache';\nimport objectHash from 'object-hash';\nimport { getCurrentContext } from '@autofleet/outbreak';\nimport { validateUUID } from '../utils';\nimport { AutofleetApiNetwork, IdentityNetwork } from '../services';\n\nexport type AccountType = 'client' | 'user' | 'service' | 'driver'\ninterface EntityPermissions {\n [key: string]: string[];\n}\n\nexport const ELEVATED_PERMISSIONS_HEADER = 'x-af-elevated-permissions';\nexport const CONTEXTS_IDS_HEADER = 'x-af-context-ids';\n\nexport interface UserPayload {\n businessModels: EntityPermissions;\n fleets: EntityPermissions;\n demandSources: EntityPermissions;\n businessAccounts?: EntityPermissions;\n accountType?: AccountType;\n contexts?: EntityPermissions;\n createdAt?: string;\n}\n\nexport interface PartialUserPayload {\n businessModels?: EntityPermissions;\n fleets?: EntityPermissions;\n demandSources?: EntityPermissions;\n vehicles?: EntityPermissions;\n drivers?: EntityPermissions;\n businessAccounts?: EntityPermissions;\n}\n\nconst userCache = new NodeCache({ stdTTL: 10 });\n\nconst mergePermissions = (target: UserPayload, sources: Iterable<PartialUserPayload>): UserPayload => {\n const permissions: UserPayload = {\n ...target,\n fleets: { ...target?.fleets },\n businessModels: { ...target?.businessModels },\n demandSources: { ...target?.demandSources },\n // Clone other nested objects as needed\n };\n\n // eslint-disable-next-line no-restricted-syntax\n for (const source of sources) {\n Object.keys(source).forEach((entityType) => {\n // eslint-disable-next-line no-param-reassign\n permissions[entityType] ??= {};\n Object.entries(source[entityType]!).forEach(([entityId, perms]) => {\n // eslint-disable-next-line no-param-reassign\n permissions[entityType][entityId] = (permissions[entityType][entityId] || []).concat(perms);\n });\n });\n }\n\n return permissions;\n};\n\nif (typeof Symbol.dispose !== 'symbol') {\n // Polyfill for dispose if it does not exist, based on https://github.com/nodejs/node/blob/9a9409ff1f45c968173118de4cd37dea784f8ec9/lib/internal/process/pre_execution.js#L163-L171\n Object.defineProperty(Symbol, 'dispose', {\n // @ts-expect-error: TypeScript does not recognize __proto__ as a valid property\n __proto__: null,\n configurable: false,\n enumerable: false,\n value: Symbol.for('nodejs.dispose'),\n writable: false,\n });\n}\nif (typeof Symbol.asyncDispose !== 'symbol') {\n // Polyfill for asyncDispose if it does not exist, based on https://github.com/nodejs/node/blob/9a9409ff1f45c968173118de4cd37dea784f8ec9/lib/internal/process/pre_execution.js#L174-L183\n Object.defineProperty(Symbol, 'asyncDispose', {\n // @ts-expect-error: TypeScript does not recognize __proto__ as a valid property\n __proto__: null,\n configurable: false,\n enumerable: false,\n value: Symbol.for('nodejs.asyncDispose'),\n writable: false,\n });\n}\n\nexport default class ApiUser {\n private privatePermissions: UserPayload | undefined;\n\n private readonly privateElevatedPermissionsHash = new Map<symbol, PartialUserPayload | undefined>();\n\n private privatePermissionsLegacy: any;\n\n private readonly appPermission: {[key: string]: any; } = {};\n\n public readonly emptyUser: boolean;\n\n constructor(public id? : string, public accountType?: AccountType, elevatedPermissions?: PartialUserPayload, public contextIds?: string[]) {\n this.emptyUser = !!id;\n if (elevatedPermissions) {\n this.privateElevatedPermissionsHash.set(Symbol('initial'), elevatedPermissions);\n }\n }\n\n public async getUserPermissions(): Promise<UserPayload> {\n if (!this.id) {\n return undefined;\n }\n if (this.privatePermissions) {\n return this.privatePermissions;\n }\n const cacheKey = objectHash({\n id: this.id,\n contextIds: this.contextIds,\n });\n\n let data = userCache.get<UserPayload>(cacheKey);\n\n if (!data) {\n ({ data } = await IdentityNetwork.get<UserPayload>(`/api/v1/users/${this.id}/authorization-payload`, { params: { contextIds: this.contextIds } }));\n userCache.set(cacheKey, data);\n }\n\n this.accountType = data.accountType;\n this.privatePermissions = data;\n return this.privatePermissions;\n }\n\n public async useCustomPermissionLoader(customPermissionLoader: (userId: string) => UserPayload | PromiseLike<UserPayload>): Promise<UserPayload> {\n if (!this.id) {\n return undefined;\n }\n if (this.privatePermissions) {\n return this.privatePermissions;\n }\n\n const cacheKey = this.id;\n\n const cachedResult = userCache.get<UserPayload>(cacheKey);\n if (cachedResult) {\n this.privatePermissions = cachedResult;\n return cachedResult;\n }\n\n const data = await customPermissionLoader(this.id);\n userCache.set(cacheKey, data);\n\n this.privatePermissions = data;\n return this.privatePermissions;\n }\n\n public get businessModels(): string[] {\n return this.getUserProperty('businessModels');\n }\n\n public get fleets(): string[] {\n return this.getUserProperty('fleets');\n }\n\n public get demandSources(): string[] {\n return this.getUserProperty('demandSources');\n }\n\n private getUserProperty(key: keyof UserPayload): string[] {\n if (!this.privatePermissions) {\n throw new Error(`Cannot get ${key} without calling (async) getUserPermissions before`);\n }\n return Object.keys(this.privatePermissions[key] || {});\n }\n\n public get elevatedPermissions(): UserPayload {\n return mergePermissions(undefined, this.privateElevatedPermissionsHash.values());\n }\n\n public get permissions(): UserPayload | undefined {\n if (!this.privatePermissions) {\n throw new Error('Cannot get permissions without calling (async) getUserPermissions before');\n }\n\n return mergePermissions(this.privatePermissions, this.privateElevatedPermissionsHash.values());\n }\n\n public elevatePermissions(addedPermissions: PartialUserPayload): (() => void) & { [Symbol.dispose]: () => void } {\n // @itayankri is concerned about memory consumption, so create a symbol with no description, to avoid assigning memory for the description string\n // eslint-disable-next-line symbol-description\n const elevationId = Symbol();\n\n // Validate that the added permissions are valid UUIDs\n Object.values(addedPermissions).forEach((entityIds) => {\n Object.keys(entityIds).forEach((entityId) => {\n if (!validateUUID(entityId)) {\n throw new Error(`Entity id on elevatePermissions is not a valid UUID, provided: ${entityId}`);\n }\n });\n });\n\n const currentUserTrace = getCurrentContext();\n if (!currentUserTrace) {\n throw new Error('Cannot find current user cross services trace');\n }\n\n const currentElevation = JSON.parse(currentUserTrace.context[ELEVATED_PERMISSIONS_HEADER] || '{}');\n const newElevation = Object.assign(currentElevation, addedPermissions);\n this.privateElevatedPermissionsHash.set(elevationId, newElevation);\n currentUserTrace.context.set(ELEVATED_PERMISSIONS_HEADER, JSON.stringify(this.elevatedPermissions));\n const cleanup = () => {\n this.privateElevatedPermissionsHash.delete(elevationId);\n currentUserTrace.context.set(ELEVATED_PERMISSIONS_HEADER, JSON.stringify(this.elevatedPermissions));\n };\n cleanup[Symbol.dispose] = cleanup;\n return cleanup;\n }\n\n public async getUserPermissionsLegacy() {\n if (!this.id) {\n return undefined;\n }\n if (this.privatePermissionsLegacy) {\n return this.privatePermissionsLegacy;\n }\n\n const cacheKey = objectHash({\n id: this.id,\n contextIds: this.contextIds,\n legacy: true,\n });\n let data = userCache.get(cacheKey);\n\n if (!data) {\n ({ data } = await IdentityNetwork.get(`/api/v1/users/${this.id}/authorization-payload-legacy`, { params: { contextIds: this.contextIds } }));\n userCache.set(cacheKey, data);\n }\n\n this.privatePermissionsLegacy = data;\n return this.privatePermissionsLegacy;\n }\n\n public get permissionsLegacy(): any {\n if (!this.privatePermissionsLegacy) {\n throw new Error('Cannot get permissionsLegacy without calling (async) getUserPermissionsLegacy before');\n }\n return this.privatePermissionsLegacy;\n }\n\n public async getUserAppPermissions(appId: string, clientSecret: string): Promise<UserPayload | undefined> {\n if (!this.id || !appId || !clientSecret) {\n return undefined;\n }\n const currentAppPermission = this.appPermission[appId];\n\n if (currentAppPermission) {\n return currentAppPermission;\n }\n\n const cacheKey = `${this.id}:${appId}`;\n\n const cachedResult = userCache.get<UserPayload>(cacheKey);\n if (cachedResult) {\n this.appPermission[appId] = cachedResult;\n return cachedResult;\n }\n\n const { data } = await AutofleetApiNetwork.post<UserPayload>(`/api/v1/apps/${appId}/get-user-payload`, {\n userId: this.id,\n }, {\n headers: {\n 'x-autofleet-apps-secret': clientSecret,\n },\n });\n\n userCache.set(cacheKey, data);\n this.appPermission[appId] = data;\n return this.appPermission[appId];\n }\n}\n","import { AutofleetApiNetwork } from './services';\n\nexport const decodeAppBearer = async (bearer: string, appId: string): Promise<any> => {\n const { data: decoded } = await AutofleetApiNetwork.post('/api/v1/auth', { bearer, appId });\n return decoded;\n};\n\nexport const getClientSecret = async (appId: string): Promise<any> => {\n const { data: secret } = await AutofleetApiNetwork.get(`/api/v1/auth/client-secret/${appId}`);\n return secret;\n};\n","export default class AppDoesNotExist extends Error {\n name = 'AppDoesNotExist';\n\n message = 'app does not exist';\n}\n","export const IDENTITY_MS = 'identity-ms';\nexport const ACCESS_TOKEN = 'accessToken';\nexport const USER_OBJECT = 'userObject';\nexport const USER_TRACING_HEADER = 'x-af-user-id';\nexport const ORIGIN_HEADER = 'X-IAF-ORIGIN-SERVICE';\nexport const USER_PERMISSIONS_HEADER = 'x-af-user-permissions';\nexport const LOWER_CASE_ORIGIN_HEADER = ORIGIN_HEADER.toLowerCase();\nexport const AUTOFLEET_APPS_SECRET_HEADER = 'x-autofleet-apps-secret';\n","import type { IncomingHttpHeaders } from 'node:http';\nimport { getCurrentContext } from '@autofleet/outbreak';\nimport ApiUser, { CONTEXTS_IDS_HEADER, ELEVATED_PERMISSIONS_HEADER, type UserPayload } from './ApiUser';\nimport {\n IDENTITY_MS,\n USER_OBJECT,\n USER_TRACING_HEADER,\n ORIGIN_HEADER,\n LOWER_CASE_ORIGIN_HEADER,\n} from './const';\n\nexport type CustomPermissionLoader = (userId: string) => Promise<UserPayload>;\nexport interface AuthFromUserIdHeaderOptions {\n eagerLoadUserPermissions?: boolean;\n eagerLoadUserPermissionsLegacy?: boolean;\n customPermissionLoader?: CustomPermissionLoader;\n}\n\nexport const authFromUserIdHeader = async (options: AuthFromUserIdHeaderOptions, headers: IncomingHttpHeaders): Promise<ApiUser | undefined> => {\n const originHeader = headers[ORIGIN_HEADER] || headers[LOWER_CASE_ORIGIN_HEADER] || '';\n if (!Array.isArray(originHeader) && originHeader.toLowerCase() === IDENTITY_MS) {\n return undefined;\n }\n const {\n eagerLoadUserPermissions,\n eagerLoadUserPermissionsLegacy,\n customPermissionLoader,\n } = options;\n const userId = headers[USER_TRACING_HEADER] as string;\n if (!userId || Array.isArray(userId)) {\n return undefined;\n }\n\n const elevatedPermissionsFromHeader = headers[ELEVATED_PERMISSIONS_HEADER]?.length > 0 ? JSON.parse(headers[ELEVATED_PERMISSIONS_HEADER] as string) : {};\n const contextIds = (headers?.[CONTEXTS_IDS_HEADER] as string)?.split(',');\n\n const userObject = new ApiUser(userId, 'user', elevatedPermissionsFromHeader, contextIds);\n if (eagerLoadUserPermissions) {\n if (customPermissionLoader) {\n await userObject.useCustomPermissionLoader(customPermissionLoader);\n } else {\n await userObject.getUserPermissions();\n }\n }\n\n if (eagerLoadUserPermissionsLegacy) {\n await userObject.getUserPermissionsLegacy();\n }\n\n getCurrentContext().nonHeaderContext?.set(USER_OBJECT, userObject);\n return userObject;\n};\n","import type { Handler, Request } from 'express';\nimport { getCurrentContext, newTrace, traceTypes } from '@autofleet/outbreak';\nimport jwt from 'jsonwebtoken';\nimport ApiUser, { CONTEXTS_IDS_HEADER } from './ApiUser';\nimport { decodeAppBearer } from '../app-auth';\nimport AppDoesNotExist from '../exceptions/appDoesNotExist';\nimport { decodeBearer, getAuthFromBearer } from '../utils';\nimport {\n ACCESS_TOKEN,\n USER_OBJECT,\n USER_TRACING_HEADER,\n USER_PERMISSIONS_HEADER,\n AUTOFLEET_APPS_SECRET_HEADER,\n} from './const';\nimport { authFromUserIdHeader, AuthFromUserIdHeaderOptions } from './common';\n\ndeclare module 'express-serve-static-core' {\n // eslint-disable-next-line @typescript-eslint/no-shadow\n interface Request {\n user: ApiUser;\n }\n}\n\nexport const middleware = (options: AuthFromUserIdHeaderOptions = {}): Handler => async (req, res, next): Promise<any> => {\n try {\n const userObject = await authFromUserIdHeader(options, req.headers);\n if (userObject) {\n req.user = userObject;\n // Added in order to support outbreak.\n // @ts-expect-error we are setting an object onto the request headers.\n req.headers[USER_PERMISSIONS_HEADER] = userObject;\n }\n\n next();\n } catch (e) {\n res.status(401).json({ error: 'cannot authenticate user' });\n }\n};\n\nexport const middlewareWithDecode = (options: {\n eagerLoadUserPermissions?: boolean;\n eagerLoadUserPermissionsLegacy?: boolean;\n returnErrorIfNoToken?: boolean\n} = {}): Handler => async (req, res, next): Promise<void> => {\n const {\n eagerLoadUserPermissions,\n eagerLoadUserPermissionsLegacy,\n returnErrorIfNoToken,\n } = options;\n let decoded;\n if (req.headers.authorization) {\n try {\n decoded = await decodeBearer(req.headers.authorization);\n } catch (e) {\n if (e instanceof jwt.TokenExpiredError) {\n res.status(401).json({ errors: ['Access token expired'] });\n } else if (e instanceof jwt.JsonWebTokenError) {\n res.status(400).json({ errors: [e.message] });\n } else {\n res.status(500).json({ errors: ['Server error while parsing token'] });\n }\n return;\n }\n const userId = decoded?.user?.id;\n\n if (userId) {\n req.headers[USER_TRACING_HEADER] = userId;\n }\n\n const contextIds = (req.headers?.[CONTEXTS_IDS_HEADER] as string)?.split(',');\n const userObject = new ApiUser(userId, decoded?.user?.accountType, undefined, contextIds);\n\n if (eagerLoadUserPermissions || eagerLoadUserPermissionsLegacy) {\n await Promise.all([\n eagerLoadUserPermissions && userObject.getUserPermissions(),\n eagerLoadUserPermissionsLegacy && userObject.getUserPermissionsLegacy(),\n ]);\n }\n\n req.user = userObject;\n getCurrentContext().nonHeaderContext?.set(USER_OBJECT, userObject);\n\n // Added in order to support outbreak.\n // @ts-expect-error we are setting an object onto the request headers.\n req.headers[USER_PERMISSIONS_HEADER] = userObject;\n } else if (returnErrorIfNoToken) {\n res.status(401).json({ errors: ['No token provided'] });\n return;\n }\n next();\n};\n\nexport const appMiddleware = (options: {\n appId: string,\n clientSecret: string\n}): Handler => async (req, res, next): Promise<void> => {\n const {\n appId,\n clientSecret,\n } = options;\n let decoded;\n\n if (!req.headers.authorization) {\n res.status(401).json({ errors: ['No token provided'] });\n return;\n }\n\n try {\n decoded = await decodeAppBearer(req.headers.authorization, appId);\n if (!decoded) {\n throw new AppDoesNotExist();\n }\n } catch (e) {\n if (e instanceof jwt.TokenExpiredError) {\n res.status(401).json({ errors: ['Access token expired'] });\n return;\n }\n if ([jwt.JsonWebTokenError, AppDoesNotExist].some((Err) => e instanceof Err)) {\n res.status(400).json({ errors: [e.message] });\n return;\n }\n res.status(500).json({ errors: ['Server error while parsing token'] });\n return;\n }\n const userId = decoded?.userId;\n if (userId) {\n req.headers[USER_TRACING_HEADER] = userId;\n }\n\n const userObject = new ApiUser(userId);\n\n if (appId) {\n req.headers[AUTOFLEET_APPS_SECRET_HEADER] = clientSecret;\n // Won't work until we find a better solution for identity ms\n await userObject.getUserAppPermissions(appId, clientSecret);\n }\n\n req.user = userObject;\n const currentTraceContext = getCurrentContext().nonHeaderContext;\n currentTraceContext?.set(USER_OBJECT, userObject);\n currentTraceContext?.set(ACCESS_TOKEN, getAuthFromBearer(req.headers.authorization));\n\n // Added in order to support outbreak.\n // @ts-expect-error we are setting an object onto the request headers.\n req.headers[USER_PERMISSIONS_HEADER] = userObject;\n\n next();\n};\n\nexport const eagerLoadPermissionsMiddleware: Handler = async (req, res, next) => {\n await req.user.getUserPermissions();\n next();\n};\n\nexport const getDecodedBearer = (req: Request) => {\n if (!req.headers.authorization) {\n return null;\n }\n return decodeBearer(req.headers.authorization);\n};\n\nexport const createOrSetRabbitTrace = async (trace: ReturnType<typeof newTrace> | undefined, userId: string | undefined) => {\n const userObject = new ApiUser(userId);\n\n await userObject.getUserPermissions();\n // eslint-disable-next-line no-param-reassign\n trace ??= newTrace(traceTypes.RABBIT);\n trace.nonHeaderContext.set(USER_OBJECT, userObject);\n};\n\nexport default ApiUser;\n","import type { FastifyPluginCallback } from 'fastify';\nimport type ApiUser from './ApiUser';\nimport { AuthFromUserIdHeaderOptions, authFromUserIdHeader } from './common';\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n user?: ApiUser;\n }\n}\n\n// eslint-disable-next-line import/prefer-default-export\nexport const authFromUserIdHeaderPlugin: FastifyPluginCallback<AuthFromUserIdHeaderOptions> = (fastify, options, done) => {\n fastify.decorateRequest('user', undefined);\n fastify.addHook('onRequest', async (request, reply) => {\n try {\n const user = await authFromUserIdHeader(options, request.headers);\n if (user) {\n request.user = user;\n }\n } catch (e) {\n reply.status(401).send({ error: 'cannot authenticate user' });\n }\n });\n\n done();\n};\nauthFromUserIdHeaderPlugin[Symbol.for('skip-override')] = true; // Prevent Fastify from overriding the plugin\n","import { getCurrentContext } from '@autofleet/outbreak';\nimport { USER_OBJECT } from './user/const';\nimport ApiUser, { type UserPayload } from './user/ApiUser';\n\nexport const getUser = () : ApiUser | undefined => getCurrentContext().nonHeaderContext?.get(USER_OBJECT) as ApiUser | undefined;\n\nexport const isUserExist = () => getUser()?.id;\n\nconst checkUserPermissions = (\n entityId: string,\n entityType: Exclude<keyof UserPayload, 'accountType' | 'createdAt'>,\n) => !isUserExist() || Object.hasOwn(getUser()!.permissions[entityType], entityId);\n\nexport const checkFleetPermission = (fleetId: string) => checkUserPermissions(fleetId, 'fleets');\nexport const checkBusinessModelPermission = (businessModelId: string) => checkUserPermissions(businessModelId, 'businessModels');\nexport const checkDemandSourcePermission = (demandSourceId: string) => checkUserPermissions(demandSourceId, 'demandSources');\n","import type ApiUser from './user';\n\n// eslint-disable-next-line import/prefer-default-export\nexport class UnauthorizedAccessError extends Error {\n constructor(public user: ApiUser | null = null, message = 'UnauthorizedAccessError') {\n super(message);\n this.name = 'UnauthorizedAccessError';\n }\n}\n","import jwt from 'jsonwebtoken';\n\nexport const AUTHORIZATION_METHODS = {\n NONE: 'NONE',\n BASIC: 'BASIC',\n JWT: 'JWT',\n};\n\nconst AUTHORIZATION_ACTIONS = {\n [AUTHORIZATION_METHODS.NONE]: () => undefined,\n [AUTHORIZATION_METHODS.BASIC]: (authorizationSettings: any) => {\n const { username, password } = authorizationSettings;\n const encodedCredentials = Buffer.from(`${username}:${password}`).toString('base64');\n return `Basic ${encodedCredentials}`;\n },\n [AUTHORIZATION_METHODS.JWT]: (authorizationSettings: any) => {\n const { secret } = authorizationSettings;\n if (secret) {\n return `Bearer ${jwt.sign({}, secret, { expiresIn: 10 })}`;\n }\n return undefined;\n },\n};\n\nexport const getAuthorizationHeader = (authorizationSettings: { method: string } | undefined): string | undefined => {\n const authorizationMethod = authorizationSettings?.method;\n\n if (!authorizationMethod || !AUTHORIZATION_ACTIONS[authorizationMethod]) {\n return undefined;\n }\n\n return AUTHORIZATION_ACTIONS[authorizationMethod](authorizationSettings);\n};\n","import type { LoggerInstanceManager } from '@autofleet/logger';\nimport * as outbreak from '@autofleet/outbreak';\nimport User, {\n middleware,\n eagerLoadPermissionsMiddleware,\n middlewareWithDecode,\n getDecodedBearer,\n appMiddleware,\n createOrSetRabbitTrace,\n} from './user';\nimport { authFromUserIdHeaderPlugin } from './user/fastify';\nimport { type UserPayload, CONTEXTS_IDS_HEADER } from './user/ApiUser';\nimport {\n checkFleetPermission,\n checkBusinessModelPermission,\n checkDemandSourcePermission,\n isUserExist,\n getUser,\n} from './check-permission';\nimport { UnauthorizedAccessError } from './errors';\nimport { getRefreshTokenSecret, getTokenSecret } from './secret-getter';\nimport { AUTHORIZATION_METHODS, getAuthorizationHeader } from './authorization';\n\nconst getCurrentPayload = outbreak.getCurrentContext;\n\ntype OutbreakOptions = Parameters<typeof outbreak.default>[0];\ntype LoggerWithContextMiddleware = Partial<Pick<LoggerInstanceManager, 'addContextMiddleware'>>;\nconst enableTracing = ({ outbreakOptions = {}, logger }: { outbreakOptions?: OutbreakOptions, logger?: LoggerWithContextMiddleware } = {}): void => {\n outbreak.default({\n headersPrefix: 'x-af',\n contextMiddlewareGetter: logger?.addContextMiddleware,\n ...outbreakOptions,\n });\n};\n\nconst { traceTypes, newTrace } = outbreak;\n\nexport {\n traceTypes,\n newTrace,\n enableTracing,\n User,\n middleware,\n middlewareWithDecode,\n eagerLoadPermissionsMiddleware,\n getCurrentPayload,\n getDecodedBearer,\n checkFleetPermission,\n checkBusinessModelPermission,\n checkDemandSourcePermission,\n isUserExist,\n getUser,\n getRefreshTokenSecret,\n getTokenSecret,\n UnauthorizedAccessError,\n appMiddleware,\n createOrSetRabbitTrace,\n outbreak,\n AUTHORIZATION_METHODS,\n getAuthorizationHeader,\n type UserPayload,\n CONTEXTS_IDS_HEADER,\n authFromUserIdHeaderPlugin,\n};\n\nexport default {\n traceTypes,\n newTrace,\n User,\n middleware,\n middlewareWithDecode,\n eagerLoadPermissionsMiddleware,\n getCurrentPayload,\n getDecodedBearer,\n checkFleetPermission,\n checkBusinessModelPermission,\n checkDemandSourcePermission,\n isUserExist,\n getUser,\n UnauthorizedAccessError,\n appMiddleware,\n createOrSetRabbitTrace,\n outbreak,\n AUTHORIZATION_METHODS,\n getAuthorizationHeader,\n CONTEXTS_IDS_HEADER,\n authFromUserIdHeaderPlugin,\n};\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/secret-getter.ts","../src/utils.ts","../src/services.ts","../src/user/ApiUser.ts","../src/app-auth.ts","../src/exceptions/appDoesNotExist.ts","../src/user/const.ts","../src/user/common.ts","../src/user/index.ts","../src/user/fastify.ts","../src/check-permission.ts","../src/errors.ts","../src/authorization.ts","../src/permissions/index.ts","../src/permissions/SDK/permissionCache.ts","../src/permissions/SDK/consts.ts","../src/permissions/SDK/evaluatePermissions.ts","../src/permissions/middleware/requirePermissions.ts","../src/index.ts"],"names":["DEPRECATED_JWT_SECRET","JWT_NEW_SECRET","DEPRECATED_REFRESH_JWT_SECRET","REFRESH_JWT_SECRET","DEPRECATION_UNIX_TIMESTAMP","getRelevantSecret","token","deprecatedSecret","newSecret","deprecationTime","moment","unixTime","iat","jwt","getRefreshTokenSecret","getTokenSecret","getAuthFromBearer","bearer","decodeBearer","appSecret","EMPTY_UUID","FULL_UUID","VALID_CHARS_REGEX","UUID_VERSION_REGEX","UUID_REGEX","validateUUID","uuid","CACHE_LIFETIME_IN_SEC","apiGwUrl","IdentityNetwork","Network","AutofleetApiNetwork","ELEVATED_PERMISSIONS_HEADER","CONTEXTS_IDS_HEADER","userCache","NodeCache","mergePermissions","target","sources","permissions","source","entityType","entityId","perms","ApiUser","id","accountType","elevatedPermissions","contextIds","cacheKey","objectHash","data","customPermissionLoader","cachedResult","key","addedPermissions","elevationId","entityIds","currentUserTrace","getCurrentContext","currentElevation","newElevation","cleanup","appId","clientSecret","currentAppPermission","decodeAppBearer","decoded","AppDoesNotExist","IDENTITY_MS","ACCESS_TOKEN","USER_OBJECT","USER_TRACING_HEADER","ORIGIN_HEADER","USER_PERMISSIONS_HEADER","LOWER_CASE_ORIGIN_HEADER","AUTOFLEET_APPS_SECRET_HEADER","authFromUserIdHeader","options","headers","originHeader","eagerLoadUserPermissions","eagerLoadUserPermissionsLegacy","userId","elevatedPermissionsFromHeader","userObject","middleware","req","res","next","middlewareWithDecode","returnErrorIfNoToken","e","appMiddleware","Err","currentTraceContext","eagerLoadPermissionsMiddleware","getDecodedBearer","createOrSetRabbitTrace","trace","newTrace","traceTypes","user_default","authFromUserIdHeaderPlugin","fastify","done","request","reply","user","getUser","isUserExist","checkUserPermissions","checkFleetPermission","fleetId","checkBusinessModelPermission","businessModelId","checkDemandSourcePermission","demandSourceId","UnauthorizedAccessError","message","AUTHORIZATION_METHODS","AUTHORIZATION_ACTIONS","authorizationSettings","username","password","secret","getAuthorizationHeader","authorizationMethod","permissions_exports","__export","permissions_default","middlewares","sdk","PermissionCache","cache","contextId","PermissionsByContextId","ttl","cacheEntries","requiredPermissions","sortedPermissions","seenKey","permissionCache","PERMISSIONS_EVALUATION_OPERATORS","PERMISSION_ERROR_TYPES","PERMISSION_ERROR_MESSAGES","evaluatePermissionsByOperator","operator","permissionsSet","matchingPermissions","permission","checkAuthorizeRequirements","permissionsEvaluationByContextId","requireAll","permissionsEvaluationValues","evaluation","validateInput","errors","createErrorResult","error","cachePermissionsResults","resolvedPermissions","permissionsToCache","contextIdsWithoutPermissions","getUnseenContextIds","seenPermissions","createSeenContextEntries","uncachedContextIds","unseenContextIds","seenContextIds","seenEntries","processCachedPermissions","cachedPermissions","processedPermissions","hasRequiredPermissions","callIdentityAPI","response","reEvaluatedPermissions","validateEvaluationInput","logger","validationErrors","resolveAllPermissions","resolvedPermissionsFromCache","seenContextEntries","resolvedPermissionsFromIdentityMS","evaluatePermissions","permissionsEvaluationOperator","timeout","resolvedUserId","validationError","isAuthorized","getContextIds","contextIdsFromHeader","contextIdsFromQuery","contextIdsFromBody","handleError","errorLabel","code","enforce","additionalInfo","requirePermissions","handleErrorWrapper","result","getCurrentPayload","enableTracing","outbreakOptions","outbreak","index_default"],"mappings":"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","file":"index.js","sourcesContent":["import jwt from 'jsonwebtoken';\nimport moment from 'moment';\n\nconst {\n DEPRECATED_JWT_SECRET, JWT_NEW_SECRET,\n DEPRECATED_REFRESH_JWT_SECRET, REFRESH_JWT_SECRET,\n DEPRECATION_UNIX_TIMESTAMP,\n} = process.env;\n\nconst getRelevantSecret = (token: string | undefined, deprecatedSecret: string, newSecret: string): string => {\n const deprecationTime = moment(parseInt(DEPRECATION_UNIX_TIMESTAMP, 10) * 1000);\n try {\n let unixTime: moment.Moment;\n if (token) {\n const { iat } = jwt.decode(token) as jwt.JwtPayload;\n unixTime = moment(iat * 1000);\n } else {\n unixTime = moment();\n }\n return unixTime.isBefore(deprecationTime) ? deprecatedSecret : newSecret;\n } catch (e) {\n return newSecret;\n }\n};\n\nexport const getRefreshTokenSecret = (token?: string): string => getRelevantSecret(token, DEPRECATED_REFRESH_JWT_SECRET, REFRESH_JWT_SECRET);\nexport const getTokenSecret = (token?: string): string => getRelevantSecret(token, DEPRECATED_JWT_SECRET, JWT_NEW_SECRET);\n","import type { UUID } from 'node:crypto';\nimport jwt from 'jsonwebtoken';\nimport { getTokenSecret } from './secret-getter';\n\ntype Context = Partial<Record<ContextProp | 'id', string>> & { subSystem?: SubSystemType; permissions?: string[]; entityId: string; };\n\nconst CONTEXT_PROPS = ['fleetId', 'businessModelId', 'demandSourceId'] as const;\ntype ContextProp = typeof CONTEXT_PROPS[number];\nconst CONTEXT_MAP_PROPS = {\n fleet: 'fleets',\n business: 'businessModels',\n demand: 'demandSources',\n} as const;\ntype SubSystemType = keyof typeof CONTEXT_MAP_PROPS;\ntype ContextSubSystemProp = typeof CONTEXT_MAP_PROPS[SubSystemType];\n\nexport const getAuthFromBearer = (bearer: string): string => bearer.replace('Bearer ', '');\n\nexport const decodeBearer = (bearer: string, appSecret?: string): any => {\n const token = getAuthFromBearer(bearer);\n const decoded = jwt.verify(token, appSecret || getTokenSecret(token));\n return decoded;\n};\n\nexport const parsePermissions = (contextId: string, decodedToken: { contexts: Context[]; }): { key: string; value: string; } | undefined => {\n if (!decodedToken) return undefined;\n const { contexts } = decodedToken;\n const activeContext = contexts.find((context) => context.id === contextId);\n\n const permissionsValue = `${activeContext.permissions?.map((cp) => `${cp},`)}`;\n\n return {\n key: activeContext.entityId,\n value: permissionsValue,\n };\n};\n\ntype EntitiesFromContext = { [key in ContextSubSystemProp]?: Record<string, string> };\nexport const getEntitiesFromContext = (contextId: string | undefined, decodedToken: { contexts: Context[]; }): EntitiesFromContext => {\n if (!decodedToken) return {};\n let { contexts } = decodedToken;\n if (contextId) {\n contexts = contexts.filter((context) => context.id === contextId);\n }\n\n const attributes: EntitiesFromContext = {};\n contexts.forEach((context) => {\n const prop = CONTEXT_MAP_PROPS[context.subSystem || 'business'];\n\n const permissions = parsePermissions(context.id, decodedToken);\n if (!permissions) return;\n attributes[prop] ||= {};\n attributes[prop][permissions.key] = permissions.value;\n });\n\n return attributes;\n};\n\ntype ContextAttributes = { [key in ContextProp]?: string[] };\nexport const getContextAttributes = (contextId: string | undefined, decodedToken: { contexts: Context[]; }): ContextAttributes => {\n if (!decodedToken) return {};\n let { contexts } = decodedToken;\n if (contextId) {\n contexts = contexts.filter((context) => context.id === contextId);\n }\n const attributes: ContextAttributes = {};\n contexts.forEach((context) => {\n CONTEXT_PROPS.forEach((prop) => {\n if (context[prop]) {\n attributes[prop] ||= [];\n attributes[prop].push(context[prop]);\n }\n });\n });\n return attributes;\n};\n\nconst EMPTY_UUID = '00000000-0000-0000-0000-000000000000';\nconst FULL_UUID = 'ffffffff-ffff-ffff-ffff-ffffffffffff';\nconst VALID_CHARS_REGEX = '[0-9a-f]';\nconst UUID_VERSION_REGEX = '[1-8]';\nconst UUID_REGEX = new RegExp(\n `^(?:${VALID_CHARS_REGEX}{8}-${VALID_CHARS_REGEX}{4}-${UUID_VERSION_REGEX}${VALID_CHARS_REGEX}{3}-[89ab]${VALID_CHARS_REGEX}{3}-${VALID_CHARS_REGEX}{12}|${EMPTY_UUID}|${FULL_UUID})$`,\n 'i',\n);\nexport function validateUUID(uuid: unknown): uuid is UUID {\n return typeof uuid === 'string' && UUID_REGEX.test(uuid);\n}\n","import Network from '@autofleet/network';\n\nconst CACHE_LIFETIME_IN_SEC = 10;\nconst apiGwUrl = process.env.API_GATEWAY_URL || 'https://api.autofleet.io';\n\n// eslint-disable-next-line import/prefer-default-export\nexport const IdentityNetwork = new Network({\n serviceName: 'IDENTITY_MS',\n retries: 3,\n retryCondition: () => true,\n cache: process.env.NODE_ENV !== 'test' ? {\n maxAge: CACHE_LIFETIME_IN_SEC * 1000,\n } : undefined,\n});\n\nexport const AutofleetApiNetwork = new Network({\n baseURL: apiGwUrl,\n serviceUrl: apiGwUrl,\n retries: 3,\n retryCondition: () => true,\n cache: process.env.NODE_ENV !== 'test' ? {\n maxAge: CACHE_LIFETIME_IN_SEC * 1000,\n } : undefined,\n});\n","import NodeCache from 'node-cache';\nimport objectHash from 'object-hash';\nimport { getCurrentContext } from '@autofleet/outbreak';\nimport { validateUUID } from '../utils';\nimport { AutofleetApiNetwork, IdentityNetwork } from '../services';\n\nexport type AccountType = 'client' | 'user' | 'service' | 'driver'\ninterface EntityPermissions {\n [key: string]: string[];\n}\n\nexport const ELEVATED_PERMISSIONS_HEADER = 'x-af-elevated-permissions';\nexport const CONTEXTS_IDS_HEADER = 'x-af-context-ids';\n\nexport interface UserPayload {\n businessModels: EntityPermissions;\n fleets: EntityPermissions;\n demandSources: EntityPermissions;\n businessAccounts?: EntityPermissions;\n accountType?: AccountType;\n contexts?: EntityPermissions;\n createdAt?: string;\n}\n\nexport interface PartialUserPayload {\n businessModels?: EntityPermissions;\n fleets?: EntityPermissions;\n demandSources?: EntityPermissions;\n vehicles?: EntityPermissions;\n drivers?: EntityPermissions;\n businessAccounts?: EntityPermissions;\n}\n\nconst userCache = new NodeCache({ stdTTL: 10 });\n\nconst mergePermissions = (target: UserPayload, sources: Iterable<PartialUserPayload>): UserPayload => {\n const permissions: UserPayload = {\n ...target,\n fleets: { ...target?.fleets },\n businessModels: { ...target?.businessModels },\n demandSources: { ...target?.demandSources },\n // Clone other nested objects as needed\n };\n\n // eslint-disable-next-line no-restricted-syntax\n for (const source of sources) {\n Object.keys(source).forEach((entityType) => {\n // eslint-disable-next-line no-param-reassign\n permissions[entityType] ??= {};\n Object.entries(source[entityType]!).forEach(([entityId, perms]) => {\n // eslint-disable-next-line no-param-reassign\n permissions[entityType][entityId] = (permissions[entityType][entityId] || []).concat(perms);\n });\n });\n }\n\n return permissions;\n};\n\nif (typeof Symbol.dispose !== 'symbol') {\n // Polyfill for dispose if it does not exist, based on https://github.com/nodejs/node/blob/9a9409ff1f45c968173118de4cd37dea784f8ec9/lib/internal/process/pre_execution.js#L163-L171\n Object.defineProperty(Symbol, 'dispose', {\n // @ts-expect-error: TypeScript does not recognize __proto__ as a valid property\n __proto__: null,\n configurable: false,\n enumerable: false,\n value: Symbol.for('nodejs.dispose'),\n writable: false,\n });\n}\nif (typeof Symbol.asyncDispose !== 'symbol') {\n // Polyfill for asyncDispose if it does not exist, based on https://github.com/nodejs/node/blob/9a9409ff1f45c968173118de4cd37dea784f8ec9/lib/internal/process/pre_execution.js#L174-L183\n Object.defineProperty(Symbol, 'asyncDispose', {\n // @ts-expect-error: TypeScript does not recognize __proto__ as a valid property\n __proto__: null,\n configurable: false,\n enumerable: false,\n value: Symbol.for('nodejs.asyncDispose'),\n writable: false,\n });\n}\n\nexport default class ApiUser {\n private privatePermissions: UserPayload | undefined;\n\n private readonly privateElevatedPermissionsHash = new Map<symbol, PartialUserPayload | undefined>();\n\n private privatePermissionsLegacy: any;\n\n private readonly appPermission: {[key: string]: any; } = {};\n\n public readonly emptyUser: boolean;\n\n constructor(public id? : string, public accountType?: AccountType, elevatedPermissions?: PartialUserPayload, public contextIds?: string[]) {\n this.emptyUser = !!id;\n if (elevatedPermissions) {\n this.privateElevatedPermissionsHash.set(Symbol('initial'), elevatedPermissions);\n }\n }\n\n public async getUserPermissions(): Promise<UserPayload> {\n if (!this.id) {\n return undefined;\n }\n if (this.privatePermissions) {\n return this.privatePermissions;\n }\n const cacheKey = objectHash({\n id: this.id,\n contextIds: this.contextIds,\n });\n\n let data = userCache.get<UserPayload>(cacheKey);\n\n if (!data) {\n ({ data } = await IdentityNetwork.get<UserPayload>(`/api/v1/users/${this.id}/authorization-payload`, { params: { contextIds: this.contextIds } }));\n userCache.set(cacheKey, data);\n }\n\n this.accountType = data.accountType;\n this.privatePermissions = data;\n return this.privatePermissions;\n }\n\n public async useCustomPermissionLoader(customPermissionLoader: (userId: string) => UserPayload | PromiseLike<UserPayload>): Promise<UserPayload> {\n if (!this.id) {\n return undefined;\n }\n if (this.privatePermissions) {\n return this.privatePermissions;\n }\n\n const cacheKey = this.id;\n\n const cachedResult = userCache.get<UserPayload>(cacheKey);\n if (cachedResult) {\n this.privatePermissions = cachedResult;\n return cachedResult;\n }\n\n const data = await customPermissionLoader(this.id);\n userCache.set(cacheKey, data);\n\n this.privatePermissions = data;\n return this.privatePermissions;\n }\n\n public get businessModels(): string[] {\n return this.getUserProperty('businessModels');\n }\n\n public get fleets(): string[] {\n return this.getUserProperty('fleets');\n }\n\n public get demandSources(): string[] {\n return this.getUserProperty('demandSources');\n }\n\n private getUserProperty(key: keyof UserPayload): string[] {\n if (!this.privatePermissions) {\n throw new Error(`Cannot get ${key} without calling (async) getUserPermissions before`);\n }\n return Object.keys(this.privatePermissions[key] || {});\n }\n\n public get elevatedPermissions(): UserPayload {\n return mergePermissions(undefined, this.privateElevatedPermissionsHash.values());\n }\n\n public get permissions(): UserPayload | undefined {\n if (!this.privatePermissions) {\n throw new Error('Cannot get permissions without calling (async) getUserPermissions before');\n }\n\n return mergePermissions(this.privatePermissions, this.privateElevatedPermissionsHash.values());\n }\n\n public elevatePermissions(addedPermissions: PartialUserPayload): (() => void) & { [Symbol.dispose]: () => void } {\n // @itayankri is concerned about memory consumption, so create a symbol with no description, to avoid assigning memory for the description string\n // eslint-disable-next-line symbol-description\n const elevationId = Symbol();\n\n // Validate that the added permissions are valid UUIDs\n Object.values(addedPermissions).forEach((entityIds) => {\n Object.keys(entityIds).forEach((entityId) => {\n if (!validateUUID(entityId)) {\n throw new Error(`Entity id on elevatePermissions is not a valid UUID, provided: ${entityId}`);\n }\n });\n });\n\n const currentUserTrace = getCurrentContext();\n if (!currentUserTrace) {\n throw new Error('Cannot find current user cross services trace');\n }\n\n const currentElevation = JSON.parse(currentUserTrace.context[ELEVATED_PERMISSIONS_HEADER] || '{}');\n const newElevation = Object.assign(currentElevation, addedPermissions);\n this.privateElevatedPermissionsHash.set(elevationId, newElevation);\n currentUserTrace.context.set(ELEVATED_PERMISSIONS_HEADER, JSON.stringify(this.elevatedPermissions));\n const cleanup = () => {\n this.privateElevatedPermissionsHash.delete(elevationId);\n currentUserTrace.context.set(ELEVATED_PERMISSIONS_HEADER, JSON.stringify(this.elevatedPermissions));\n };\n cleanup[Symbol.dispose] = cleanup;\n return cleanup;\n }\n\n public async getUserPermissionsLegacy() {\n if (!this.id) {\n return undefined;\n }\n if (this.privatePermissionsLegacy) {\n return this.privatePermissionsLegacy;\n }\n\n const cacheKey = objectHash({\n id: this.id,\n contextIds: this.contextIds,\n legacy: true,\n });\n let data = userCache.get(cacheKey);\n\n if (!data) {\n ({ data } = await IdentityNetwork.get(`/api/v1/users/${this.id}/authorization-payload-legacy`, { params: { contextIds: this.contextIds } }));\n userCache.set(cacheKey, data);\n }\n\n this.privatePermissionsLegacy = data;\n return this.privatePermissionsLegacy;\n }\n\n public get permissionsLegacy(): any {\n if (!this.privatePermissionsLegacy) {\n throw new Error('Cannot get permissionsLegacy without calling (async) getUserPermissionsLegacy before');\n }\n return this.privatePermissionsLegacy;\n }\n\n public async getUserAppPermissions(appId: string, clientSecret: string): Promise<UserPayload | undefined> {\n if (!this.id || !appId || !clientSecret) {\n return undefined;\n }\n const currentAppPermission = this.appPermission[appId];\n\n if (currentAppPermission) {\n return currentAppPermission;\n }\n\n const cacheKey = `${this.id}:${appId}`;\n\n const cachedResult = userCache.get<UserPayload>(cacheKey);\n if (cachedResult) {\n this.appPermission[appId] = cachedResult;\n return cachedResult;\n }\n\n const { data } = await AutofleetApiNetwork.post<UserPayload>(`/api/v1/apps/${appId}/get-user-payload`, {\n userId: this.id,\n }, {\n headers: {\n 'x-autofleet-apps-secret': clientSecret,\n },\n });\n\n userCache.set(cacheKey, data);\n this.appPermission[appId] = data;\n return this.appPermission[appId];\n }\n}\n","import { AutofleetApiNetwork } from './services';\n\nexport const decodeAppBearer = async (bearer: string, appId: string): Promise<any> => {\n const { data: decoded } = await AutofleetApiNetwork.post('/api/v1/auth', { bearer, appId });\n return decoded;\n};\n\nexport const getClientSecret = async (appId: string): Promise<any> => {\n const { data: secret } = await AutofleetApiNetwork.get(`/api/v1/auth/client-secret/${appId}`);\n return secret;\n};\n","export default class AppDoesNotExist extends Error {\n name = 'AppDoesNotExist';\n\n message = 'app does not exist';\n}\n","export const IDENTITY_MS = 'identity-ms';\nexport const ACCESS_TOKEN = 'accessToken';\nexport const USER_OBJECT = 'userObject';\nexport const USER_TRACING_HEADER = 'x-af-user-id';\nexport const ORIGIN_HEADER = 'X-IAF-ORIGIN-SERVICE';\nexport const USER_PERMISSIONS_HEADER = 'x-af-user-permissions';\nexport const LOWER_CASE_ORIGIN_HEADER = ORIGIN_HEADER.toLowerCase();\nexport const AUTOFLEET_APPS_SECRET_HEADER = 'x-autofleet-apps-secret';\n","import type { IncomingHttpHeaders } from 'node:http';\nimport { getCurrentContext } from '@autofleet/outbreak';\nimport ApiUser, { CONTEXTS_IDS_HEADER, ELEVATED_PERMISSIONS_HEADER, type UserPayload } from './ApiUser';\nimport {\n IDENTITY_MS,\n USER_OBJECT,\n USER_TRACING_HEADER,\n ORIGIN_HEADER,\n LOWER_CASE_ORIGIN_HEADER,\n} from './const';\n\nexport type CustomPermissionLoader = (userId: string) => Promise<UserPayload>;\nexport interface AuthFromUserIdHeaderOptions {\n eagerLoadUserPermissions?: boolean;\n eagerLoadUserPermissionsLegacy?: boolean;\n customPermissionLoader?: CustomPermissionLoader;\n}\n\nexport const authFromUserIdHeader = async (options: AuthFromUserIdHeaderOptions, headers: IncomingHttpHeaders): Promise<ApiUser | undefined> => {\n const originHeader = headers[ORIGIN_HEADER] || headers[LOWER_CASE_ORIGIN_HEADER] || '';\n if (!Array.isArray(originHeader) && originHeader.toLowerCase() === IDENTITY_MS) {\n return undefined;\n }\n const {\n eagerLoadUserPermissions,\n eagerLoadUserPermissionsLegacy,\n customPermissionLoader,\n } = options;\n const userId = headers[USER_TRACING_HEADER] as string;\n if (!userId || Array.isArray(userId)) {\n return undefined;\n }\n\n const elevatedPermissionsFromHeader = headers[ELEVATED_PERMISSIONS_HEADER]?.length > 0 ? JSON.parse(headers[ELEVATED_PERMISSIONS_HEADER] as string) : {};\n const contextIds = (headers?.[CONTEXTS_IDS_HEADER] as string)?.split(',');\n\n const userObject = new ApiUser(userId, 'user', elevatedPermissionsFromHeader, contextIds);\n if (eagerLoadUserPermissions) {\n if (customPermissionLoader) {\n await userObject.useCustomPermissionLoader(customPermissionLoader);\n } else {\n await userObject.getUserPermissions();\n }\n }\n\n if (eagerLoadUserPermissionsLegacy) {\n await userObject.getUserPermissionsLegacy();\n }\n\n getCurrentContext().nonHeaderContext?.set(USER_OBJECT, userObject);\n return userObject;\n};\n","import type { Handler, Request } from 'express';\nimport { getCurrentContext, newTrace, traceTypes } from '@autofleet/outbreak';\nimport jwt from 'jsonwebtoken';\nimport ApiUser, { CONTEXTS_IDS_HEADER } from './ApiUser';\nimport { decodeAppBearer } from '../app-auth';\nimport AppDoesNotExist from '../exceptions/appDoesNotExist';\nimport { decodeBearer, getAuthFromBearer } from '../utils';\nimport {\n ACCESS_TOKEN,\n USER_OBJECT,\n USER_TRACING_HEADER,\n USER_PERMISSIONS_HEADER,\n AUTOFLEET_APPS_SECRET_HEADER,\n} from './const';\nimport { authFromUserIdHeader, AuthFromUserIdHeaderOptions } from './common';\n\ndeclare module 'express-serve-static-core' {\n // eslint-disable-next-line @typescript-eslint/no-shadow\n interface Request {\n user: ApiUser;\n }\n}\n\nexport const middleware = (options: AuthFromUserIdHeaderOptions = {}): Handler => async (req, res, next): Promise<any> => {\n try {\n const userObject = await authFromUserIdHeader(options, req.headers);\n if (userObject) {\n req.user = userObject;\n // Added in order to support outbreak.\n // @ts-expect-error we are setting an object onto the request headers.\n req.headers[USER_PERMISSIONS_HEADER] = userObject;\n }\n\n next();\n } catch (e) {\n res.status(401).json({ error: 'cannot authenticate user' });\n }\n};\n\nexport const middlewareWithDecode = (options: {\n eagerLoadUserPermissions?: boolean;\n eagerLoadUserPermissionsLegacy?: boolean;\n returnErrorIfNoToken?: boolean\n} = {}): Handler => async (req, res, next): Promise<void> => {\n const {\n eagerLoadUserPermissions,\n eagerLoadUserPermissionsLegacy,\n returnErrorIfNoToken,\n } = options;\n let decoded;\n if (req.headers.authorization) {\n try {\n decoded = await decodeBearer(req.headers.authorization);\n } catch (e) {\n if (e instanceof jwt.TokenExpiredError) {\n res.status(401).json({ errors: ['Access token expired'] });\n } else if (e instanceof jwt.JsonWebTokenError) {\n res.status(400).json({ errors: [e.message] });\n } else {\n res.status(500).json({ errors: ['Server error while parsing token'] });\n }\n return;\n }\n const userId = decoded?.user?.id;\n\n if (userId) {\n req.headers[USER_TRACING_HEADER] = userId;\n }\n\n const contextIds = (req.headers?.[CONTEXTS_IDS_HEADER] as string)?.split(',');\n const userObject = new ApiUser(userId, decoded?.user?.accountType, undefined, contextIds);\n\n if (eagerLoadUserPermissions || eagerLoadUserPermissionsLegacy) {\n await Promise.all([\n eagerLoadUserPermissions && userObject.getUserPermissions(),\n eagerLoadUserPermissionsLegacy && userObject.getUserPermissionsLegacy(),\n ]);\n }\n\n req.user = userObject;\n getCurrentContext().nonHeaderContext?.set(USER_OBJECT, userObject);\n\n // Added in order to support outbreak.\n // @ts-expect-error we are setting an object onto the request headers.\n req.headers[USER_PERMISSIONS_HEADER] = userObject;\n } else if (returnErrorIfNoToken) {\n res.status(401).json({ errors: ['No token provided'] });\n return;\n }\n next();\n};\n\nexport const appMiddleware = (options: {\n appId: string,\n clientSecret: string\n}): Handler => async (req, res, next): Promise<void> => {\n const {\n appId,\n clientSecret,\n } = options;\n let decoded;\n\n if (!req.headers.authorization) {\n res.status(401).json({ errors: ['No token provided'] });\n return;\n }\n\n try {\n decoded = await decodeAppBearer(req.headers.authorization, appId);\n if (!decoded) {\n throw new AppDoesNotExist();\n }\n } catch (e) {\n if (e instanceof jwt.TokenExpiredError) {\n res.status(401).json({ errors: ['Access token expired'] });\n return;\n }\n if ([jwt.JsonWebTokenError, AppDoesNotExist].some((Err) => e instanceof Err)) {\n res.status(400).json({ errors: [e.message] });\n return;\n }\n res.status(500).json({ errors: ['Server error while parsing token'] });\n return;\n }\n const userId = decoded?.userId;\n if (userId) {\n req.headers[USER_TRACING_HEADER] = userId;\n }\n\n const userObject = new ApiUser(userId);\n\n if (appId) {\n req.headers[AUTOFLEET_APPS_SECRET_HEADER] = clientSecret;\n // Won't work until we find a better solution for identity ms\n await userObject.getUserAppPermissions(appId, clientSecret);\n }\n\n req.user = userObject;\n const currentTraceContext = getCurrentContext().nonHeaderContext;\n currentTraceContext?.set(USER_OBJECT, userObject);\n currentTraceContext?.set(ACCESS_TOKEN, getAuthFromBearer(req.headers.authorization));\n\n // Added in order to support outbreak.\n // @ts-expect-error we are setting an object onto the request headers.\n req.headers[USER_PERMISSIONS_HEADER] = userObject;\n\n next();\n};\n\nexport const eagerLoadPermissionsMiddleware: Handler = async (req, res, next) => {\n await req.user.getUserPermissions();\n next();\n};\n\nexport const getDecodedBearer = (req: Request) => {\n if (!req.headers.authorization) {\n return null;\n }\n return decodeBearer(req.headers.authorization);\n};\n\nexport const createOrSetRabbitTrace = async (trace: ReturnType<typeof newTrace> | undefined, userId: string | undefined) => {\n const userObject = new ApiUser(userId);\n\n await userObject.getUserPermissions();\n // eslint-disable-next-line no-param-reassign\n trace ??= newTrace(traceTypes.RABBIT);\n trace.nonHeaderContext.set(USER_OBJECT, userObject);\n};\n\nexport default ApiUser;\n","import type { FastifyPluginCallback } from 'fastify';\nimport type ApiUser from './ApiUser';\nimport { AuthFromUserIdHeaderOptions, authFromUserIdHeader } from './common';\n\ndeclare module 'fastify' {\n interface FastifyRequest {\n user?: ApiUser;\n }\n}\n\n// eslint-disable-next-line import/prefer-default-export\nexport const authFromUserIdHeaderPlugin: FastifyPluginCallback<AuthFromUserIdHeaderOptions> = (fastify, options, done) => {\n fastify.decorateRequest('user', undefined);\n fastify.addHook('onRequest', async (request, reply) => {\n try {\n const user = await authFromUserIdHeader(options, request.headers);\n if (user) {\n request.user = user;\n }\n } catch (e) {\n reply.status(401).send({ error: 'cannot authenticate user' });\n }\n });\n\n done();\n};\nauthFromUserIdHeaderPlugin[Symbol.for('skip-override')] = true; // Prevent Fastify from overriding the plugin\n","import { getCurrentContext } from '@autofleet/outbreak';\nimport { USER_OBJECT } from './user/const';\nimport ApiUser, { type UserPayload } from './user/ApiUser';\n\nexport const getUser = () : ApiUser | undefined => getCurrentContext().nonHeaderContext?.get(USER_OBJECT) as ApiUser | undefined;\n\nexport const isUserExist = () => getUser()?.id;\n\nconst checkUserPermissions = (\n entityId: string,\n entityType: Exclude<keyof UserPayload, 'accountType' | 'createdAt'>,\n) => !isUserExist() || Object.hasOwn(getUser()!.permissions[entityType], entityId);\n\nexport const checkFleetPermission = (fleetId: string) => checkUserPermissions(fleetId, 'fleets');\nexport const checkBusinessModelPermission = (businessModelId: string) => checkUserPermissions(businessModelId, 'businessModels');\nexport const checkDemandSourcePermission = (demandSourceId: string) => checkUserPermissions(demandSourceId, 'demandSources');\n","import type ApiUser from './user';\n\n// eslint-disable-next-line import/prefer-default-export\nexport class UnauthorizedAccessError extends Error {\n constructor(public user: ApiUser | null = null, message = 'UnauthorizedAccessError') {\n super(message);\n this.name = 'UnauthorizedAccessError';\n }\n}\n","import jwt from 'jsonwebtoken';\n\nexport const AUTHORIZATION_METHODS = {\n NONE: 'NONE',\n BASIC: 'BASIC',\n JWT: 'JWT',\n};\n\nconst AUTHORIZATION_ACTIONS = {\n [AUTHORIZATION_METHODS.NONE]: () => undefined,\n [AUTHORIZATION_METHODS.BASIC]: (authorizationSettings: any) => {\n const { username, password } = authorizationSettings;\n const encodedCredentials = Buffer.from(`${username}:${password}`).toString('base64');\n return `Basic ${encodedCredentials}`;\n },\n [AUTHORIZATION_METHODS.JWT]: (authorizationSettings: any) => {\n const { secret } = authorizationSettings;\n if (secret) {\n return `Bearer ${jwt.sign({}, secret, { expiresIn: 10 })}`;\n }\n return undefined;\n },\n};\n\nexport const getAuthorizationHeader = (authorizationSettings: { method: string } | undefined): string | undefined => {\n const authorizationMethod = authorizationSettings?.method;\n\n if (!authorizationMethod || !AUTHORIZATION_ACTIONS[authorizationMethod]) {\n return undefined;\n }\n\n return AUTHORIZATION_ACTIONS[authorizationMethod](authorizationSettings);\n};\n","import { evaluatePermissions } from './SDK/evaluatePermissions';\nimport { requirePermissions } from './middleware/requirePermissions';\n\nexport const sdk = {\n evaluatePermissions,\n};\n\nexport const middlewares = {\n requirePermissions,\n};\n\nexport default {\n sdk,\n middlewares,\n};\n","import NodeCache from 'node-cache';\n\ninterface EntityPermissions {\n [key: string]: string[];\n}\n\nexport class PermissionCache {\n private cache: NodeCache;\n\n /**\n * Creates a new PermissionCache instance\n * @param cache - Optional NodeCache instance. If not provided, creates a new one with default TTL of 10 seconds\n */\n constructor(cache?: NodeCache) {\n this.cache = cache || new NodeCache({ stdTTL: 10 });\n }\n\n /**\n * Retrieves user permissions for multiple contexts from cache\n * @param userId - The user identifier\n * @param contextIds - Array of context identifiers to fetch permissions for\n * @returns Promise that resolves to an object mapping context IDs to permission arrays\n */\n public async getUserPermissions(userId: string, contextIds: string[]): Promise<EntityPermissions> {\n try {\n const cacheKey = (contextId) => `perm-${userId}-${contextId}`;\n\n return await this.cache.mget(contextIds.map(cacheKey)) as EntityPermissions;\n } catch (error) {\n return {};\n }\n }\n\n /**\n * Stores user permissions for multiple contexts in cache\n * @param userId - The user identifier\n * @param PermissionsByContextId - Object mapping context IDs to permission arrays\n * @param ttl - Optional time to live in seconds. Defaults to 10 seconds\n * @returns Promise that resolves to an object indicating success/failure\n */\n public async setUserPermissions(userId: string, PermissionsByContextId: EntityPermissions, ttl?: number): Promise<{ success: boolean }> {\n try {\n const cacheKey = (contextId) => `perm-${userId}-${contextId}`;\n\n const cacheEntries = Object.entries(PermissionsByContextId).map(([contextId, permissions]) => ({\n key: cacheKey(contextId),\n val: permissions,\n ttl: ttl ?? 10,\n }));\n\n await this.cache.mset(cacheEntries);\n\n return { success: true };\n } catch (error) {\n return { success: false };\n }\n }\n\n /**\n * Retrieves seen permissions status for multiple contexts from cache.\n * \"Seen\" permissions indicate that a user has already been evaluated for a specific set of\n * required permissions in a given context, avoiding redundant permission checks.\n * @param userId - The user identifier\n * @param contextIds - Array of context identifiers to check\n * @param requiredPermissions - Array of required permissions to check if previously evaluated\n * @returns Promise that resolves to an object mapping context IDs to boolean values indicating if permissions were previously evaluated\n */\n public async getSeenPermissions(userId: string, contextIds: string[], requiredPermissions: string[]): Promise<Record<string, boolean>> {\n try {\n const sortedPermissions = requiredPermissions.sort().join(',');\n const seenKey = (contextId: string) => `seen-${userId}-${contextId}-${sortedPermissions}`;\n\n return await this.cache.mget(contextIds.map(seenKey)) as Record<string, boolean>;\n } catch (error) {\n return {};\n }\n }\n\n /**\n * Marks permissions as seen for multiple contexts in cache.\n * \"Seen\" permissions are used to track that a user has already been evaluated for a specific\n * set of required permissions in given contexts, preventing duplicate permission evaluations.\n * @param userId - The user identifier\n * @param contextIds - Array of context identifiers to mark as seen\n * @param requiredPermissions - Array of required permissions that have been evaluated\n * @param ttl - Optional time to live in seconds. Defaults to 10 seconds\n * @returns Promise that resolves to an object indicating success/failure\n */\n public async setSeenPermissions(userId: string, contextIds: string[], requiredPermissions: string[], ttl?: number): Promise<{ success: boolean }> {\n try {\n const sortedPermissions = requiredPermissions.sort().join(',');\n const seenKey = (contextId: string) => `seen-${userId}-${contextId}-${sortedPermissions}`;\n\n const cacheEntries = contextIds.map((contextId) => ({\n key: seenKey(contextId),\n val: true,\n ttl: ttl ?? 10,\n }));\n\n await this.cache.mset(cacheEntries);\n\n return { success: true };\n } catch (error) {\n return { success: false };\n }\n }\n}\n\nexport const permissionCache = new PermissionCache();\n","export const PERMISSIONS_EVALUATION_OPERATORS = {\n AND: 'and',\n OR: 'or',\n};\n\nexport const PERMISSION_ERROR_TYPES = {\n USER_NOT_FOUND: 'USER_NOT_FOUND',\n INSUFFICIENT_PERMISSIONS: 'INSUFFICIENT_PERMISSIONS',\n VALIDATION_ERROR: 'VALIDATION_ERROR',\n API_ERROR: 'API_ERROR',\n NO_REQUIRED_PERMISSIONS: 'NO_REQUIRED_PERMISSIONS',\n UNAUTHORIZED: 'UNAUTHORIZED',\n BAD_REQUEST: 'BAD_REQUEST',\n INTERNAL_ERROR: 'INTERNAL_ERROR',\n};\n\nexport const PERMISSION_ERROR_MESSAGES = {\n USER_NOT_FOUND: 'User not found',\n INSUFFICIENT_PERMISSIONS: 'User does not have sufficient permissions',\n VALIDATION_ERROR: 'Validation error occurred',\n API_ERROR: 'API error occurred',\n NO_REQUIRED_PERMISSIONS: 'No required permissions provided for evaluation',\n UNAUTHORIZED: 'User is not authorized to perform this action',\n BAD_REQUEST: 'Bad request, please check the input parameters',\n INTERNAL_ERROR: 'Internal server error occurred while checking permissions',\n};\n","import { getUser } from '../../check-permission';\nimport { IdentityNetwork } from '../../services';\nimport {\n PermissionsEvaluationOperator,\n type EvaluatePermissionsParams,\n type PermissionsEvaluationByContextId,\n type PermissionCheckResult,\n type ResolvePermissionsParams,\n type Logger,\n PermissionsByContextId,\n} from './types';\nimport { type PermissionErrorType } from './errors';\nimport { permissionCache } from './permissionCache';\nimport { PERMISSIONS_EVALUATION_OPERATORS, PERMISSION_ERROR_TYPES } from './consts';\n\n/**\n * Evaluates whether user permissions meet requirements based on AND/OR operator\n * @param permissions - User's actual permissions\n * @param requiredPermissions - Required permissions to check against\n * @param operator - {@link PermissionsEvaluationOperator} AND (all required) or OR (at least one required)\n * @returns true if permissions meet requirements\n */\nconst evaluatePermissionsByOperator = (\n permissions: string[],\n requiredPermissions: string[],\n operator: PermissionsEvaluationOperator,\n): boolean => {\n const permissionsSet = new Set(permissions);\n const matchingPermissions = requiredPermissions.filter((permission) => permissionsSet.has(permission));\n\n return operator === PERMISSIONS_EVALUATION_OPERATORS.AND\n ? matchingPermissions.length === requiredPermissions.length // All required permissions must be present\n : matchingPermissions.length > 0; // At least one required permission must be present\n};\n\n/**\n * Creates empty permissions result for cases with no required permissions\n * @param contextIds - Context IDs to create results for\n * @returns {@link PermissionsEvaluationByContextId} with empty permissions and granted access\n */\nconst createEmptyPermissionsResult = (contextIds: string[]): PermissionsEvaluationByContextId => Object.fromEntries(\n contextIds.map((contextId) => [\n contextId,\n { permissions: [], hasRequiredPermissions: true },\n ]),\n);\n\n/**\n * Checks if permission requirements are met across all contexts\n * @param permissionsEvaluationByContextId - {@link PermissionsEvaluationByContextId} Permission evaluation results by context\n * @param requireAll - Whether all contexts must satisfy requirements (true) or just one (false)\n * @returns true if requirements are met\n */\nexport const checkAuthorizeRequirements = (permissionsEvaluationByContextId: PermissionsEvaluationByContextId, requireAll: boolean) => {\n const permissionsEvaluationValues = Object.values(permissionsEvaluationByContextId);\n\n if (requireAll) {\n return permissionsEvaluationValues.every((evaluation) => evaluation.hasRequiredPermissions);\n }\n return permissionsEvaluationValues.some((evaluation) => evaluation.hasRequiredPermissions);\n};\n\n/**\n * Resolves permissions from Identity Service API\n * @param params - {@link ResolvePermissionsParams}\n * @returns {@link PermissionsEvaluationByContextId} Permission evaluation results by context ID\n */\nexport const resolvePermissions = async ({\n user,\n contextIds,\n requiredPermissions,\n options,\n}: ResolvePermissionsParams): Promise<PermissionsEvaluationByContextId> => {\n if (!requiredPermissions?.length) {\n return createEmptyPermissionsResult(contextIds);\n }\n\n const response = await IdentityNetwork.post('/api/v1/permissions/resolve', {\n userId: user.id,\n contextIds,\n requiredPermissions,\n }, {\n timeout: options.timeout,\n });\n\n const { data }: { data: PermissionsEvaluationByContextId } = response;\n\n if (!Object.keys(data || {}).length) {\n throw new Error('Failed to resolve permissions');\n }\n\n if (options.permissionsEvaluationOperator === PERMISSIONS_EVALUATION_OPERATORS.AND) {\n return data;\n }\n\n const permissionsEvaluationByContextId: PermissionsEvaluationByContextId = {};\n Object.entries(data).forEach(([contextId, evaluation]) => {\n const permissions = evaluation?.permissions || [];\n const hasRequiredPermissions = evaluatePermissionsByOperator(\n permissions,\n requiredPermissions,\n options.permissionsEvaluationOperator,\n );\n\n permissionsEvaluationByContextId[contextId] = {\n permissions,\n hasRequiredPermissions,\n };\n });\n\n return permissionsEvaluationByContextId;\n};\n\n/**\n * Resolves permissions from user's cached permissions\n * @param params - {@link ResolvePermissionsParams}\n * @returns {@link PermissionsEvaluationByContextId} Permission evaluation results by context ID from cache\n */\nexport const resolvePermissionsFromCache = async ({\n user,\n contextIds,\n requiredPermissions,\n options,\n}: ResolvePermissionsParams): Promise<PermissionsEvaluationByContextId> => {\n const cachedPermissions = await permissionCache.getUserPermissions(user.id, contextIds);\n\n if (!Object.keys(cachedPermissions || {}).length) {\n return {};\n }\n\n const permissionsEvaluationByContextId: PermissionsEvaluationByContextId = {};\n\n Object.entries(cachedPermissions).forEach(([contextId, permissions]) => {\n const hasRequiredPermissions = evaluatePermissionsByOperator(\n permissions,\n requiredPermissions,\n options.permissionsEvaluationOperator,\n );\n\n permissionsEvaluationByContextId[contextId] = {\n permissions,\n hasRequiredPermissions,\n };\n });\n\n return permissionsEvaluationByContextId;\n};\n\nconst validateInput = (contextIds: string[]): string[] => {\n const errors: string[] = [];\n\n if (!contextIds?.length) {\n errors.push('contextIds cannot be empty');\n }\n\n return errors;\n};\n\nconst createErrorResult = (\n error: PermissionErrorType,\n requiredPermissions: string[],\n contextIds: string[],\n message?: string,\n): PermissionCheckResult => ({\n isAuthorized: false,\n error,\n resolvedPermissions: {},\n requiredPermissions,\n contextIds,\n ...(message && { message }),\n});\n\n/**\n * Caches permission results based on whether they meet requirements\n */\nconst cachePermissionsResults = async (\n userId: string,\n resolvedPermissions: PermissionsEvaluationByContextId,\n requiredPermissions: string[],\n): Promise<void> => {\n const permissionsToCache: PermissionsByContextId = {};\n const contextIdsWithoutPermissions: string[] = [];\n\n Object.entries(resolvedPermissions).forEach(([contextId, evaluation]) => {\n if (evaluation?.permissions) {\n if (evaluation.hasRequiredPermissions) {\n permissionsToCache[contextId] = evaluation.permissions;\n } else {\n contextIdsWithoutPermissions.push(contextId);\n }\n }\n });\n\n if (Object.keys(permissionsToCache).length > 0) {\n await permissionCache.setUserPermissions(userId, permissionsToCache);\n }\n\n if (contextIdsWithoutPermissions.length > 0) {\n await permissionCache.setSeenPermissions(userId, contextIdsWithoutPermissions, requiredPermissions);\n }\n};\n\n/**\n * Filters context IDs to only those that haven't been seen before\n * Seen context IDs are those for which the user has already been denied permissions\n */\nconst getUnseenContextIds = async (\n userId: string,\n contextIds: string[],\n requiredPermissions: string[],\n): Promise<string[]> => {\n const seenPermissions = await permissionCache.getSeenPermissions(userId, contextIds, requiredPermissions);\n return contextIds.filter((contextId) => !seenPermissions[`seen-${userId}-${contextId}-${requiredPermissions.sort().join(',')}`]);\n};\n\n/**\n * Creates entries for \"seen\" contexts that were previously denied permissions\n * @param uncachedContextIds - Context IDs that weren't found in cache\n * @param unseenContextIds - Context IDs that haven't been processed before\n * @returns Object with entries for seen contexts marked as having no required permissions\n */\nconst createSeenContextEntries = (\n uncachedContextIds: string[],\n unseenContextIds: string[],\n): PermissionsEvaluationByContextId => {\n const seenContextIds = uncachedContextIds.filter((contextId) => !unseenContextIds.includes(contextId));\n const seenEntries: PermissionsEvaluationByContextId = {};\n\n seenContextIds.forEach((contextId) => {\n seenEntries[contextId] = {\n permissions: [],\n hasRequiredPermissions: false,\n };\n });\n\n return seenEntries;\n};\n\n/**\n * Processes cached permissions into evaluation format\n * @param cachedPermissions - Raw permissions from cache\n * @param requiredPermissions - Required permissions to evaluate against\n * @param operator - Evaluation operator (AND/OR)\n * @returns Processed permissions evaluation\n */\nconst processCachedPermissions = (\n cachedPermissions: Record<string, string[]>,\n requiredPermissions: string[],\n operator: PermissionsEvaluationOperator,\n): PermissionsEvaluationByContextId => {\n const processedPermissions: PermissionsEvaluationByContextId = {};\n\n if (Object.keys(cachedPermissions || {}).length) {\n Object.entries(cachedPermissions).forEach(([contextId, permissions]) => {\n const hasRequiredPermissions = evaluatePermissionsByOperator(\n permissions,\n requiredPermissions,\n operator,\n );\n\n processedPermissions[contextId] = {\n permissions,\n hasRequiredPermissions,\n };\n });\n }\n\n return processedPermissions;\n};\n\n/**\n * Calls the Identity API to resolve permissions for unseen contexts\n * @param userId - User ID\n * @param contextIds - Context IDs to resolve\n * @param requiredPermissions - Required permissions\n * @param options - API call options\n * @returns Resolved permissions from API\n */\nconst callIdentityAPI = async (\n userId: string,\n contextIds: string[],\n requiredPermissions: string[],\n options: { permissionsEvaluationOperator: PermissionsEvaluationOperator; timeout: number },\n): Promise<PermissionsEvaluationByContextId> => {\n const response = await IdentityNetwork.post('/api/v1/permissions/resolve', {\n userId,\n contextIds,\n requiredPermissions,\n }, {\n timeout: options.timeout,\n });\n\n const { data }: { data: PermissionsEvaluationByContextId } = response;\n\n if (!Object.keys(data || {}).length) {\n throw new Error('Failed to resolve permissions');\n }\n\n // If using AND operator, return data as-is. For OR, re-evaluate.\n if (options.permissionsEvaluationOperator === PERMISSIONS_EVALUATION_OPERATORS.AND) {\n return data;\n }\n\n // Re-evaluate with OR operator\n const reEvaluatedPermissions: PermissionsEvaluationByContextId = {};\n Object.entries(data).forEach(([contextId, evaluation]) => {\n const permissions = evaluation?.permissions || [];\n const hasRequiredPermissions = evaluatePermissionsByOperator(\n permissions,\n requiredPermissions,\n options.permissionsEvaluationOperator,\n );\n\n reEvaluatedPermissions[contextId] = {\n permissions,\n hasRequiredPermissions,\n };\n });\n\n return reEvaluatedPermissions;\n};\n\n/**\n * Validates user context and required permissions for evaluation\n * @param contextIds - Context IDs to validate\n * @param requiredPermissions - Required permissions to validate\n * @param userId - User ID to validate\n * @param logger - Logger instance for warnings\n * @returns Error result if validation fails, null if validation passes\n */\nconst validateEvaluationInput = (\n contextIds: string[],\n requiredPermissions: string[],\n userId: string | null,\n logger: Logger,\n): PermissionCheckResult | null => {\n const validationErrors = validateInput(contextIds);\n if (validationErrors.length) {\n return createErrorResult(PERMISSION_ERROR_TYPES.VALIDATION_ERROR, requiredPermissions, contextIds, validationErrors.join(', '));\n }\n\n if (!userId) {\n logger?.warn('User not found in context, cannot check permissions', {\n contextIds,\n requiredPermissions,\n });\n return createErrorResult(PERMISSION_ERROR_TYPES.USER_NOT_FOUND, requiredPermissions, contextIds);\n }\n\n if (!requiredPermissions?.length) {\n logger?.info('No requiredPermissions provided', {\n userId,\n contextIds,\n });\n return {\n isAuthorized: false,\n userId,\n resolvedPermissions: {},\n requiredPermissions,\n contextIds,\n error: PERMISSION_ERROR_TYPES.NO_REQUIRED_PERMISSIONS,\n };\n }\n\n return null;\n};\n\n/**\n * Resolves permissions from multiple sources (cache, seen contexts, API)\n * @param userId - User ID\n * @param contextIds - Context IDs to resolve permissions for\n * @param requiredPermissions - Required permissions to check\n * @param options - Evaluation options\n * @returns Combined permissions from all sources\n */\nconst resolveAllPermissions = async (\n userId: string,\n contextIds: string[],\n requiredPermissions: string[],\n options: { permissionsEvaluationOperator: PermissionsEvaluationOperator; timeout: number },\n): Promise<PermissionsEvaluationByContextId> => {\n // Process cached permissions\n const cachedPermissions = await permissionCache.getUserPermissions(userId, contextIds);\n const resolvedPermissionsFromCache = processCachedPermissions(\n cachedPermissions,\n requiredPermissions,\n options.permissionsEvaluationOperator,\n );\n let resolvedPermissions = { ...resolvedPermissionsFromCache };\n\n // Handle uncached contexts\n const uncachedContextIds = contextIds.filter((contextId) => !resolvedPermissionsFromCache[contextId]);\n const unseenContextIds = await getUnseenContextIds(userId, uncachedContextIds, requiredPermissions);\n\n // Add entries for seen contexts (previously denied)\n const seenContextEntries = createSeenContextEntries(uncachedContextIds, unseenContextIds);\n resolvedPermissions = { ...resolvedPermissions, ...seenContextEntries };\n\n // Resolve unseen contexts from API\n if (unseenContextIds.length) {\n const resolvedPermissionsFromIdentityMS = await callIdentityAPI(\n userId,\n unseenContextIds,\n requiredPermissions,\n options,\n );\n\n resolvedPermissions = {\n ...resolvedPermissions,\n ...resolvedPermissionsFromIdentityMS,\n };\n\n await cachePermissionsResults(userId, resolvedPermissionsFromIdentityMS, requiredPermissions);\n }\n\n return resolvedPermissions;\n};\n\n/**\n * Main SDK function to evaluate user permissions\n * Checks both cached and API-resolved permissions to determine access\n * @param params - {@link EvaluatePermissionsParams}\n * @returns {@link PermissionCheckResult} Detailed permission check result with access status and context\n */\nexport const evaluatePermissions = async ({\n requiredPermissions,\n contextIds,\n logger,\n userId,\n options: {\n requireAll = true,\n permissionsEvaluationOperator = PERMISSIONS_EVALUATION_OPERATORS.AND,\n timeout = 10000,\n },\n}: EvaluatePermissionsParams): Promise<PermissionCheckResult> => {\n const resolvedUserId = userId || getUser()?.id || null;\n\n const validationError = validateEvaluationInput(contextIds, requiredPermissions, resolvedUserId, logger);\n if (validationError) {\n return validationError;\n }\n\n const resolvedPermissions = await resolveAllPermissions(\n resolvedUserId!,\n contextIds,\n requiredPermissions,\n { permissionsEvaluationOperator, timeout },\n );\n\n const isAuthorized = checkAuthorizeRequirements(resolvedPermissions, requireAll);\n\n logger?.info('Resolved permissions', {\n userId: resolvedUserId,\n requiredPermissions,\n isAuthorized,\n requireAll,\n permissionsEvaluationOperator,\n contextIds,\n });\n\n return {\n isAuthorized,\n userId: resolvedUserId!,\n resolvedPermissions,\n requiredPermissions,\n contextIds,\n ...(isAuthorized ? {} : { error: PERMISSION_ERROR_TYPES.INSUFFICIENT_PERMISSIONS }),\n };\n};\n\nexport default evaluatePermissions;\n","import type { Request, Response, NextFunction } from 'express';\nimport type { LoggerInstanceManager } from '@autofleet/logger';\nimport { evaluatePermissions } from '../SDK/evaluatePermissions';\nimport type { EvaluatePermissionsOpts } from '../SDK/types';\nimport { getUser } from '../../check-permission';\nimport { CONTEXTS_IDS_HEADER } from '../../user/ApiUser';\nimport { PERMISSION_ERROR_MESSAGES, PERMISSION_ERROR_TYPES, PERMISSIONS_EVALUATION_OPERATORS } from '../SDK/consts';\n\nexport interface RequirePermissionsOptions extends EvaluatePermissionsOpts {\n logger?: LoggerInstanceManager;\n}\n\nconst getContextIds = (req: Request): string[] => {\n const contextIdsFromHeader = (req.headers?.[CONTEXTS_IDS_HEADER] as string)?.split(',') || [];\n const contextIdsFromQuery = (req.query?.contextIds as string)?.split(',') || [];\n const contextIdsFromBody = (req.body?.contextIds as string[]) || [];\n\n return Array.from(new Set([...contextIdsFromHeader, ...contextIdsFromQuery, ...contextIdsFromBody])).filter(Boolean);\n};\n\nconst handleError = (\n errorLabel: string,\n message: string,\n code: number,\n enforce: boolean,\n res: Response,\n req: Request,\n next: NextFunction,\n logger?: LoggerInstanceManager,\n additionalInfo?: Record<string, unknown>,\n) => {\n if (enforce) {\n logger?.error(message, {\n url: req.url,\n method: req.method,\n requiredPermissions: additionalInfo?.requiredPermissions || [],\n ...additionalInfo,\n });\n\n return res.status(code).json({\n error: errorLabel,\n message,\n ...(additionalInfo?.requiredPermissions && { requiredPermissions: additionalInfo.requiredPermissions }),\n });\n }\n\n logger?.warn(message, {\n url: req.url,\n method: req.method,\n requiredPermissions: additionalInfo?.requiredPermissions || [],\n ...additionalInfo,\n });\n return next();\n};\n\n/**\n * Express middleware that requires specific permissions for route access\n *\n * @param requiredPermissions - Array of permissions required to access the route\n * @param options - Configuration options for permission checking\n * @returns Express middleware function\n */\nexport const requirePermissions = (\n requiredPermissions: string[],\n options: RequirePermissionsOptions = {\n enforce: false,\n requireAll: true,\n permissionsEvaluationOperator: PERMISSIONS_EVALUATION_OPERATORS.AND,\n },\n) => async (req: Request, res: Response, next: NextFunction) => {\n try {\n const {\n logger,\n enforce,\n requireAll,\n permissionsEvaluationOperator,\n } = options;\n\n const handleErrorWrapper = (errorLabel: string, message: string, code: number) => handleError(\n errorLabel,\n message,\n code,\n enforce,\n res,\n req,\n next,\n logger,\n { requiredPermissions },\n );\n\n const user = getUser();\n if (!user?.id) {\n return handleErrorWrapper(\n PERMISSION_ERROR_TYPES.UNAUTHORIZED,\n PERMISSION_ERROR_MESSAGES.UNAUTHORIZED,\n 401,\n );\n }\n\n const contextIds: string[] = getContextIds(req);\n if (!contextIds?.length) {\n return handleErrorWrapper(\n PERMISSION_ERROR_TYPES.BAD_REQUEST,\n PERMISSION_ERROR_MESSAGES.BAD_REQUEST,\n 400,\n );\n }\n\n // Evaluate permissions using SDK\n const result = await evaluatePermissions({\n requiredPermissions,\n contextIds,\n logger,\n userId: user.id,\n options: {\n requireAll: requireAll ?? true,\n permissionsEvaluationOperator: permissionsEvaluationOperator ?? PERMISSIONS_EVALUATION_OPERATORS.AND,\n timeout: 10000,\n },\n });\n\n if (result.isAuthorized) {\n logger?.info('User has required permissions', {\n userId: user.id,\n requiredPermissions,\n contextIds,\n url: req.url,\n method: req.method,\n });\n return next();\n }\n\n if (!enforce) {\n logger?.warn('User does not have required permissions, skipping enforcement', {\n userId: user.id,\n requiredPermissions,\n contextIds,\n url: req.url,\n method: req.method,\n });\n return next();\n }\n\n return res.status(403).json({\n error: PERMISSION_ERROR_TYPES.INSUFFICIENT_PERMISSIONS,\n message: PERMISSION_ERROR_MESSAGES.INSUFFICIENT_PERMISSIONS,\n required: requiredPermissions,\n contexts: contextIds,\n userId: result.userId,\n });\n } catch (error) {\n const requestLogger = options.logger;\n requestLogger?.error('Error in requirePermissions middleware', {\n error,\n requiredPermissions,\n url: req.url,\n method: req.method,\n });\n\n if (!options.enforce) {\n options.logger?.error('Error during permission check, skipping enforcement', {\n error,\n url: req.url,\n method: req.method,\n });\n return next();\n }\n\n return res.status(500).json({\n error: PERMISSION_ERROR_TYPES.INTERNAL_ERROR,\n message: PERMISSION_ERROR_MESSAGES.INTERNAL_ERROR,\n });\n }\n};\n\nexport default requirePermissions;\n","import type { LoggerInstanceManager } from '@autofleet/logger';\nimport * as outbreak from '@autofleet/outbreak';\nimport User, {\n middleware,\n eagerLoadPermissionsMiddleware,\n middlewareWithDecode,\n getDecodedBearer,\n appMiddleware,\n createOrSetRabbitTrace,\n} from './user';\nimport { authFromUserIdHeaderPlugin } from './user/fastify';\nimport { type UserPayload, CONTEXTS_IDS_HEADER } from './user/ApiUser';\nimport {\n checkFleetPermission,\n checkBusinessModelPermission,\n checkDemandSourcePermission,\n isUserExist,\n getUser,\n} from './check-permission';\nimport { UnauthorizedAccessError } from './errors';\nimport { getRefreshTokenSecret, getTokenSecret } from './secret-getter';\nimport { AUTHORIZATION_METHODS, getAuthorizationHeader } from './authorization';\nimport * as permissions from './permissions';\n\nconst getCurrentPayload = outbreak.getCurrentContext;\n\ntype OutbreakOptions = Parameters<typeof outbreak.default>[0];\ntype LoggerWithContextMiddleware = Partial<Pick<LoggerInstanceManager, 'addContextMiddleware'>>;\nconst enableTracing = ({ outbreakOptions = {}, logger }: { outbreakOptions?: OutbreakOptions, logger?: LoggerWithContextMiddleware } = {}): void => {\n outbreak.default({\n headersPrefix: 'x-af',\n contextMiddlewareGetter: logger?.addContextMiddleware,\n ...outbreakOptions,\n });\n};\n\nconst { traceTypes, newTrace } = outbreak;\n\nexport {\n traceTypes,\n newTrace,\n enableTracing,\n User,\n middleware,\n middlewareWithDecode,\n eagerLoadPermissionsMiddleware,\n getCurrentPayload,\n getDecodedBearer,\n checkFleetPermission,\n checkBusinessModelPermission,\n checkDemandSourcePermission,\n isUserExist,\n getUser,\n getRefreshTokenSecret,\n getTokenSecret,\n UnauthorizedAccessError,\n appMiddleware,\n createOrSetRabbitTrace,\n outbreak,\n AUTHORIZATION_METHODS,\n getAuthorizationHeader,\n type UserPayload,\n CONTEXTS_IDS_HEADER,\n authFromUserIdHeaderPlugin,\n permissions,\n};\n\nexport default {\n traceTypes,\n newTrace,\n User,\n middleware,\n middlewareWithDecode,\n eagerLoadPermissionsMiddleware,\n getCurrentPayload,\n getDecodedBearer,\n checkFleetPermission,\n checkBusinessModelPermission,\n checkDemandSourcePermission,\n isUserExist,\n getUser,\n UnauthorizedAccessError,\n appMiddleware,\n createOrSetRabbitTrace,\n outbreak,\n AUTHORIZATION_METHODS,\n getAuthorizationHeader,\n CONTEXTS_IDS_HEADER,\n authFromUserIdHeaderPlugin,\n permissions,\n};\n"]}
|