@shopware-ag/admin-extension-sdk
Advanced tools
Comparing version 0.0.30 to 0.0.31
@@ -1,1 +0,1 @@ | ||
var _e=Object.defineProperty;var E=Object.getOwnPropertySymbols;var ge=Object.prototype.hasOwnProperty,fe=Object.prototype.propertyIsEnumerable;var T=(o,r,i)=>r in o?_e(o,r,{enumerable:!0,configurable:!0,writable:!0,value:i}):o[r]=i,m=(o,r)=>{for(var i in r||(r={}))ge.call(r,i)&&T(o,i,r[i]);if(E)for(var i of E(r))fe.call(r,i)&&T(o,i,r[i]);return o};(function(o,r){typeof exports=="object"&&typeof module!="undefined"?r(exports):typeof define=="function"&&define.amd?define(["exports"],r):(o=typeof globalThis!="undefined"?globalThis:o||self,r(o.sw={}))})(this,function(o){var O;"use strict";function r(){return String(Date.now().toString(36)+Math.random().toString(36).substr(2))}function i(e,t){for(let s in e){const n=e[s];t.apply(this,[e,s,n]),y(n)&&i(n,t)}}function y(e){return e!==null&&typeof e=="object"}function w(){return new URLSearchParams(window.location.search).get("location-id")}function x(){const e=window.location;return new URL(e.pathname,e.origin).toString()}function H(e){k(e)}function j(e){N(e)}const S={};let M=!1;function P(){M||(M=!0,b("__function__",async({args:e,id:t})=>await Promise.resolve(S[t](...e))))}function k(e){i(e,(t,s,n)=>{if(typeof n=="function"){const a=r();S[a]=n,t[s]={__type__:"__function__",id:a},P()}})}function N(e){i(e,(t,s,n)=>{if(y(n)&&n.__type__&&n.__type__==="__function__"&&typeof n.id=="string"){const a=n.id;t[s]=(...d)=>l("__function__",{args:d,id:a})}})}const I=new Set;function l(e,t,s){const n=r(),a=t!=null?t:{},d={_type:e,_data:a,_callbackId:n};H(d);const f=JSON.stringify(d);let u=!1;const p=3e3;return new Promise((de,ue)=>{const z=function(v){if(typeof v.data!="string")return;let g;try{g=JSON.parse(v.data)}catch{return}!U(g)||g._callbackId===n&&(!g.hasOwnProperty("_response")||(window.removeEventListener("message",z),u||(u=!0,de(g._response))))};window.addEventListener("message",z);let h=!0;try{h=!window.parent.origin}catch{}const le=!h&&window.parent.__CYPRESS__?window:window.parent,D=h?document.referrer:window.parent.origin;s?s.postMessage(f,D):le.postMessage(f,D),setTimeout(()=>{u||ue("Send timeout expired. It could be possible that no handler for the postMessage request exists or that the handler freezed.")},p)})}function b(e,t){const s=async function(n){var p;if(typeof n.data!="string")return;let a;try{a=JSON.parse(n.data)}catch{return}if(!C(a)||a._type!==e)return;j(a);const d=await Promise.resolve(t(a._data,{_event_:n})),f={_callbackId:a._callbackId,_type:a._type,_response:d!=null?d:null},u=JSON.stringify(f);n.source?n.source.postMessage(u,{targetOrigin:(p=n.origin)!=null?p:"*"}):window.postMessage(u,window.origin)};return window.addEventListener("message",s),()=>window.removeEventListener("message",s)}function A(e,t){return b(e,t)}function c(e,t){return s=>l(e,m(m({},t),s))}function L(e){return t=>A(e,t)}(async()=>{b("__registerWindow__",(e,t)=>{t._event_.source?I.add(t._event_.source):I.add(window)}),await l("__registerWindow__",{})})().catch(e=>console.error(e));function C(e){const t=e;return!!t._type&&!!t._data&&!!t._callbackId}function U(e){const t=e;return!!t._type&&!!t.hasOwnProperty("_response")&&!!t._callbackId}const W=c("windowRedirect"),J=c("windowReload",{});var $=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",redirect:W,reload:J});const q=c("notificationDispatch");var Y=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",dispatch:q});const B=c("contextLanguage",{}),F=L("contextLanguage"),G=c("contextEnvironment",{}),K=c("contextLocale",{}),Q=L("contextLocale"),X=c("contextCurrency",{});var Z=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",getLanguage:B,subscribeLanguage:F,getEnvironment:G,getLocale:K,subscribeLocale:Q,getCurrency:X});const V=c("uiComponentSectionRenderer",{src:(O=x())!=null?O:void 0});var ee=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",add:V}),te=e=>({addTabItem:c("uiTabsAddTabItem",{positionId:e})});const ne=e=>w()===e,oe=()=>window!==window.parent,R=e=>{if(e)return l("locationUpdateHeight",{height:e,locationId:w()});const t=document.documentElement.offsetHeight;return l("locationUpdateHeight",{height:t,locationId:w()})};let _=null;const re=()=>{_=new ResizeObserver(()=>{R()}),_.observe(document.body)},ie=()=>{_&&(_.unobserve(document.body),_.disconnect())},se="sw-main-hidden";var ae=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",is:ne,isIframe:oe,updateHeight:R,startAutoResizer:re,stopAutoResizer:ie,MAIN_HIDDEN:se});const ce={componentSection:ee,tabs:te};o.context=Z,o.location=ae,o.notification=Y,o.ui=ce,o.window=$,Object.defineProperty(o,"__esModule",{value:!0}),o[Symbol.toStringTag]="Module"}); | ||
var Me=Object.defineProperty;var N=Object.getOwnPropertySymbols;var Pe=Object.prototype.hasOwnProperty,Le=Object.prototype.propertyIsEnumerable;var M=(o,s,c)=>s in o?Me(o,s,{enumerable:!0,configurable:!0,writable:!0,value:c}):o[s]=c,P=(o,s)=>{for(var c in s||(s={}))Pe.call(s,c)&&M(o,c,s[c]);if(N)for(var c of N(s))Le.call(s,c)&&M(o,c,s[c]);return o};var U=(o,s,c)=>(M(o,typeof s!="symbol"?s+"":s,c),c);(function(o,s){typeof exports=="object"&&typeof module!="undefined"?s(exports):typeof define=="function"&&define.amd?define(["exports"],s):(o=typeof globalThis!="undefined"?globalThis:o||self,s(o.sw={}))})(this,function(o){var z;"use strict";function s(){return String(Date.now().toString(36)+Math.random().toString(36).substr(2))}function c(e,t){for(let n in e){const i=e[n];t.apply(this,[e,n,i]),L(i)&&c(i,t)}}function L(e){return e!==null&&typeof e=="object"}function m(){return new URLSearchParams(window.location.search).get("location-id")}function A(){const e=window.location;return new URL(e.pathname,e.origin).toString()}function C(e){J(e)}function $(e){q(e)}const O={};let I=!1;function W(){if(I)return;I=!0,K({})("__function__",async({args:t,id:n})=>await Promise.resolve(O[n](...t)))}function J(e){c(e,(t,n,i)=>{if(typeof i=="function"){const r=s();O[r]=i,t[n]={__type__:"__function__",id:r},W()}})}function q(e){c(e,(t,n,i)=>{if(L(i)&&i.__type__&&i.__type__==="__function__"&&typeof i.id=="string"){const r=i.id;t[n]=(...a)=>f("__function__",{args:a,id:r})}})}const b={notificationDispatch:{},windowRedirect:{},windowReload:{},contextLanguage:{},contextEnvironment:{},contextLocale:{},contextCurrency:{},getPageTitle:{},uiComponentSectionRenderer:{},uiTabsAddTabItem:{},locationUpdateHeight:{},__function__:{},__registerWindow__:{},_multiply:{},_subtract:{},_privileges:{create:["user"],read:["user"],update:["user"],delete:["user"]}};function B(e){const t=R(e),n=Y(window.location);return!t||Object.keys(t).length<=0?null:E(t,n)}function F(e,t,n){const i=R(e),r=G(t,n);return r?E(i,r.permissions):null}function R(e){return b[e]}function Y(e){const n=new URLSearchParams(e.search).get("privileges");return n?JSON.parse(n):{}}function E(e,t){const n=Object.keys(e),i=[];return n.forEach(r=>{var a;(a=e[r])==null||a.forEach(d=>{var l;((l=t[r])==null?void 0:l.includes(d))||i.push(`${r}:${d}`)})}),i.length>=1?i:null}function G(e,t){let n=null;return Object.values(e).forEach(i=>{i.baseUrl===t&&(n=i)}),n}class y extends Error{constructor(t,n){super(`Your app is missing the priviliges ${n.join(", ")} for action "${t}".`);U(this,"missingPrivileges");this.missingPrivileges=n,Object.setPrototypeOf(this,y.prototype)}}const j=new Set;function f(e,t,n){const i=B(e);if(i!==null){const h=new y(e,i);return Promise.reject(h)}const r=s(),a=t!=null?t:{},d={_type:e,_data:a,_callbackId:r};C(d);const l=JSON.stringify(d);let g=!1;const w=3e3;return new Promise((h,ve)=>{const T=function(k){if(typeof k.data!="string")return;let p;try{p=JSON.parse(k.data)}catch{return}!Z(p)||p._callbackId===r&&(!p.hasOwnProperty("_response")||(window.removeEventListener("message",T),g||(g=!0,h(p._response))))};window.addEventListener("message",T);let S=!0;try{S=!window.parent.origin}catch{}const Se=!S&&window.parent.__CYPRESS__?window:window.parent,H=S?document.referrer:window.parent.origin;n?n.postMessage(l,H):Se.postMessage(l,H),setTimeout(()=>{g||ve("Send timeout expired. It could be possible that no handler for the postMessage request exists or that the handler freezed.")},w)})}function v(e,t,n){const i=async function(r){var w;if(b[e]&&Object.keys(b[e]).length&&(!n||F(e,n,r.origin)!==null)||typeof r.data!="string")return;let a;try{a=JSON.parse(r.data)}catch{return}if(!X(a)||a._type!==e)return;$(a);const d=await Promise.resolve(t(a._data,{_event_:r})),l={_callbackId:a._callbackId,_type:a._type,_response:d!=null?d:null},g=JSON.stringify(l);r.source?r.source.postMessage(g,{targetOrigin:(w=r.origin)!=null?w:"*"}):window.postMessage(g,window.origin)};return window.addEventListener("message",i),()=>window.removeEventListener("message",i)}function K(e){return(t,n)=>v(t,n,e)}function Q(e,t){return v(e,t,{})}function u(e,t){return n=>f(e,P(P({},t),n))}function x(e){return t=>Q(e,t)}(async()=>{v("__registerWindow__",(e,t)=>{t._event_.source?j.add(t._event_.source):j.add(window)},{}),await f("__registerWindow__",{})})().catch(e=>console.error(e));function X(e){const t=e;return!!t._type&&!!t._data&&!!t._callbackId}function Z(e){const t=e;return!!t._type&&!!t.hasOwnProperty("_response")&&!!t._callbackId}const V=u("windowRedirect"),ee=u("windowReload",{});var te=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",redirect:V,reload:ee});const ne=u("notificationDispatch");var ie=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",dispatch:ne});const re=u("contextLanguage",{}),oe=x("contextLanguage"),se=u("contextEnvironment",{}),ce=u("contextLocale",{}),ae=x("contextLocale"),ue=u("contextCurrency",{});var de=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",getLanguage:re,subscribeLanguage:oe,getEnvironment:se,getLocale:ce,subscribeLocale:ae,getCurrency:ue});const le=u("uiComponentSectionRenderer",{src:(z=A())!=null?z:void 0});var ge=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",add:le}),fe=e=>({addTabItem:u("uiTabsAddTabItem",{positionId:e})});const _e=e=>m()===e,pe=()=>window!==window.parent,D=e=>{if(e)return f("locationUpdateHeight",{height:e,locationId:m()});const t=document.documentElement.offsetHeight;return f("locationUpdateHeight",{height:t,locationId:m()})};let _=null;const we=()=>{_=new ResizeObserver(()=>{D()}),_.observe(document.body)},he=()=>{_&&(_.unobserve(document.body),_.disconnect())},me="sw-main-hidden";var be=Object.freeze({__proto__:null,[Symbol.toStringTag]:"Module",is:_e,isIframe:pe,updateHeight:D,startAutoResizer:we,stopAutoResizer:he,MAIN_HIDDEN:me});const ye={componentSection:ge,tabs:fe};o.context=de,o.location=be,o.notification=ie,o.ui=ye,o.window=te,Object.defineProperty(o,"__esModule",{value:!0}),o[Symbol.toStringTag]="Module"}); |
@@ -10,3 +10,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
}; | ||
import { send, handle } from '../channel'; | ||
import { send, handleFactory } from '../channel'; | ||
import { traverseObject, isObject, generateUniqueId } from './utils'; | ||
@@ -27,2 +27,3 @@ /* eslint-disable */ | ||
isMethodHandlerStarted = true; | ||
const handle = handleFactory({}); | ||
handle('__function__', ({ args, id }) => __awaiter(this, void 0, void 0, function* () { | ||
@@ -29,0 +30,0 @@ return yield Promise.resolve(methodRegistry[id](...args)); |
import { ShopwareMessageTypes } from './messages.types'; | ||
import { extensions } from './privileges/privilege-resolver'; | ||
/** | ||
@@ -43,15 +44,9 @@ * ---------------- | ||
export declare function send<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, data: MessageDataType<MESSAGE_TYPE>, targetWindow?: Window): Promise<ShopwareMessageTypes[MESSAGE_TYPE]['responseType'] | null>; | ||
/** | ||
* | ||
* @param type Choose a type of action from the {@link send-types} | ||
* @param method This method should return the response value | ||
* @returns The return value is a cancel function to stop listening to the events | ||
*/ | ||
export declare function handle<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, method: (data: MessageDataType<MESSAGE_TYPE>, additionalInformation: { | ||
export declare function handleFactory(extensions: extensions): <MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, method: (data: MessageDataType<MESSAGE_TYPE>, additionalInformation: { | ||
_event_: MessageEvent<string>; | ||
}) => Promise<ShopwareMessageTypes[MESSAGE_TYPE]['responseType']> | ShopwareMessageTypes[MESSAGE_TYPE]['responseType']): () => void; | ||
}) => ShopwareMessageTypes[MESSAGE_TYPE]["responseType"] | Promise<ShopwareMessageTypes[MESSAGE_TYPE]["responseType"]>) => () => void; | ||
export declare function publish<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, data: ShopwareMessageTypes[MESSAGE_TYPE]['responseType']): Promise<(void | Promise<ShopwareMessageTypes[MESSAGE_TYPE]['responseType']> | null)[]>; | ||
export declare function subscribe<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, method: (data: ShopwareMessageTypes[MESSAGE_TYPE]['responseType']) => void | Promise<unknown>): () => void; | ||
/** | ||
* Factory method which creates a sender so that the type don't need to be | ||
* Factory method which creates a sender so that the type doesn't need to be | ||
* defined and can be hidden. Also this allows to use a send method without | ||
@@ -58,0 +53,0 @@ * a required second argument if the default options are defined. |
@@ -12,2 +12,5 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import { generateUniqueId } from './_internals/utils'; | ||
import { sendPrivileged, handlePrivileged } from './privileges/privilege-resolver'; | ||
import { ShopwareMessageTypePrivileges } from './privileges'; | ||
import MissingPrivilegesError from './privileges/missing-privileges-error'; | ||
/** | ||
@@ -32,2 +35,7 @@ * ---------------- | ||
export function send(type, data, targetWindow) { | ||
const missingPriviliges = sendPrivileged(type); | ||
if (missingPriviliges !== null) { | ||
const missingPrivilegesError = new MissingPrivilegesError(type, missingPriviliges); | ||
return Promise.reject(missingPrivilegesError); | ||
} | ||
// Generate a unique callback ID. This here is only for simple demonstration purposes | ||
@@ -113,6 +121,16 @@ const callbackId = generateUniqueId(); | ||
*/ | ||
export function handle(type, method) { | ||
function handle(type, method, extensions) { | ||
const handleListener = function (event) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// Message type needs privileges to be handled | ||
if (ShopwareMessageTypePrivileges[type] && Object.keys(ShopwareMessageTypePrivileges[type]).length) { | ||
if (!extensions) { | ||
return; | ||
} | ||
const missingPrivileges = handlePrivileged(type, extensions, event.origin); | ||
if (missingPrivileges !== null) { | ||
return; | ||
} | ||
} | ||
if (typeof event.data !== 'string') { | ||
@@ -165,2 +183,5 @@ return; | ||
} | ||
export function handleFactory(extensions) { | ||
return (type, method) => handle(type, method, extensions); | ||
} | ||
export function publish(type, data) { | ||
@@ -175,3 +196,3 @@ const sendPromises = [...sourceRegistry].map((source) => { | ||
export function subscribe(type, method) { | ||
return handle(type, method); | ||
return handle(type, method, {}); | ||
} | ||
@@ -192,3 +213,3 @@ // MAIN FUNCTION WHICH INCLUDES ALL POSSIBILITES | ||
return (method) => { | ||
return handle(messageType, method); | ||
return handle(messageType, method, {}); | ||
}; | ||
@@ -220,3 +241,3 @@ } | ||
} | ||
}); | ||
}, {}); | ||
// Register at parent window | ||
@@ -223,0 +244,0 @@ yield send('__registerWindow__', {}); |
@@ -10,6 +10,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
}; | ||
import { send, handle, createSender, createHandler, subscribe, publish } from './channel'; | ||
import { send, handleFactory, createSender, createHandler, subscribe, publish } from './channel'; | ||
import MissingPrivilegesError from './privileges/missing-privileges-error'; | ||
describe('Test the channel bridge from iFrame to admin', () => { | ||
const defaultHandle = handleFactory({}); | ||
it('should send "reload" command to the admin', (done) => { | ||
const removeListener = handle('windowReload', (result) => { | ||
const removeListener = defaultHandle('windowReload', (result) => { | ||
expect(result).toEqual({}); | ||
@@ -22,3 +24,3 @@ removeListener(); | ||
it('should send "reload" command to the admin also without options', (done) => { | ||
const removeListener = handle('windowReload', (result) => { | ||
const removeListener = defaultHandle('windowReload', (result) => { | ||
expect(result).toEqual({}); | ||
@@ -34,3 +36,3 @@ removeListener(); | ||
const PAGE_TITLE = 'Awesome page title'; | ||
const removeListener = handle('getPageTitle', () => { | ||
const removeListener = defaultHandle('getPageTitle', () => { | ||
return PAGE_TITLE; | ||
@@ -138,3 +140,32 @@ }); | ||
})); | ||
it('should reject send with missing privileges', () => { | ||
send('_privileges', {}).catch(e => { | ||
const expectedError = new MissingPrivilegesError('_privileges', ['create:user', 'read:user', 'update:user', 'delete:user']); | ||
expect(e.message).toEqual(expectedError.message); | ||
}); | ||
}); | ||
it('should not call handle callback with missing extensions', () => { | ||
const callback = jest.fn(); | ||
const removeHandle = defaultHandle('_privileges', callback); | ||
// Simulate a postMessage call from an iFrame | ||
window.dispatchEvent(new Event('message')); | ||
removeHandle(); | ||
expect(callback).toHaveBeenCalledTimes(0); | ||
}); | ||
it('should not call handle callback with missing privileges', () => { | ||
const url = 'http://example.com'; | ||
const callback = jest.fn(); | ||
const handle = handleFactory({ foo: { baseUrl: url, permissions: { create: ['notification'] } } }); | ||
const removeHandle = handle('_privileges', callback); | ||
const event = new Event('message'); | ||
// Simulate a postMessage call from an iFrame with a none registered origin | ||
window.dispatchEvent(event); | ||
// Simulate a postMessage call from an iFrame | ||
// @ts-expect-error | ||
event.origin = url; | ||
window.dispatchEvent(event); | ||
removeHandle(); | ||
expect(callback).toHaveBeenCalledTimes(0); | ||
}); | ||
}); | ||
//# sourceMappingURL=channel.spec.js.map |
@@ -27,2 +27,3 @@ import { notificationDispatch } from './notification/index'; | ||
_subtract: _subtract; | ||
_privileges: _privileges; | ||
}; | ||
@@ -51,2 +52,5 @@ /** | ||
}; | ||
export declare type _privileges = { | ||
responseType: void; | ||
}; | ||
export declare type __function__ = { | ||
@@ -53,0 +57,0 @@ responseType: any; |
{ | ||
"name": "@shopware-ag/admin-extension-sdk", | ||
"version": "0.0.30", | ||
"version": "0.0.31", | ||
"repository": "git://github.com/shopware/admin-extension-sdk.git", | ||
@@ -55,2 +55,3 @@ "description": "The SDK for App iframes to communicate with the Shopware Adminstration", | ||
"eslint": "^8.3.0", | ||
"eslint-plugin-import": "^2.25.4", | ||
"jest": "^27.3.1", | ||
@@ -57,0 +58,0 @@ "live-server": "^1.2.1", |
@@ -40,3 +40,4 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
isMethodHandlerStarted = true; | ||
(0, channel_1.handle)('__function__', ({ args, id }) => __awaiter(this, void 0, void 0, function* () { | ||
const handle = (0, channel_1.handleFactory)({}); | ||
handle('__function__', ({ args, id }) => __awaiter(this, void 0, void 0, function* () { | ||
return yield Promise.resolve(methodRegistry[id](...args)); | ||
@@ -43,0 +44,0 @@ })); |
import { ShopwareMessageTypes } from './messages.types'; | ||
import { extensions } from './privileges/privilege-resolver'; | ||
/** | ||
@@ -43,15 +44,9 @@ * ---------------- | ||
export declare function send<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, data: MessageDataType<MESSAGE_TYPE>, targetWindow?: Window): Promise<ShopwareMessageTypes[MESSAGE_TYPE]['responseType'] | null>; | ||
/** | ||
* | ||
* @param type Choose a type of action from the {@link send-types} | ||
* @param method This method should return the response value | ||
* @returns The return value is a cancel function to stop listening to the events | ||
*/ | ||
export declare function handle<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, method: (data: MessageDataType<MESSAGE_TYPE>, additionalInformation: { | ||
export declare function handleFactory(extensions: extensions): <MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, method: (data: MessageDataType<MESSAGE_TYPE>, additionalInformation: { | ||
_event_: MessageEvent<string>; | ||
}) => Promise<ShopwareMessageTypes[MESSAGE_TYPE]['responseType']> | ShopwareMessageTypes[MESSAGE_TYPE]['responseType']): () => void; | ||
}) => ShopwareMessageTypes[MESSAGE_TYPE]["responseType"] | Promise<ShopwareMessageTypes[MESSAGE_TYPE]["responseType"]>) => () => void; | ||
export declare function publish<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, data: ShopwareMessageTypes[MESSAGE_TYPE]['responseType']): Promise<(void | Promise<ShopwareMessageTypes[MESSAGE_TYPE]['responseType']> | null)[]>; | ||
export declare function subscribe<MESSAGE_TYPE extends keyof ShopwareMessageTypes>(type: MESSAGE_TYPE, method: (data: ShopwareMessageTypes[MESSAGE_TYPE]['responseType']) => void | Promise<unknown>): () => void; | ||
/** | ||
* Factory method which creates a sender so that the type don't need to be | ||
* Factory method which creates a sender so that the type doesn't need to be | ||
* defined and can be hidden. Also this allows to use a send method without | ||
@@ -58,0 +53,0 @@ * a required second argument if the default options are defined. |
@@ -10,2 +10,5 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
(function (factory) { | ||
@@ -17,3 +20,3 @@ if (typeof module === "object" && typeof module.exports === "object") { | ||
else if (typeof define === "function" && define.amd) { | ||
define(["require", "exports", "./_internals/function-serializer", "./_internals/utils"], factory); | ||
define(["require", "exports", "./_internals/function-serializer", "./_internals/utils", "./privileges/privilege-resolver", "./privileges", "./privileges/missing-privileges-error"], factory); | ||
} | ||
@@ -23,5 +26,8 @@ })(function (require, exports) { | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.createSubscriber = exports.createHandler = exports.createSender = exports.subscribe = exports.publish = exports.handle = exports.send = void 0; | ||
exports.createSubscriber = exports.createHandler = exports.createSender = exports.subscribe = exports.publish = exports.handleFactory = exports.send = void 0; | ||
const function_serializer_1 = require("./_internals/function-serializer"); | ||
const utils_1 = require("./_internals/utils"); | ||
const privilege_resolver_1 = require("./privileges/privilege-resolver"); | ||
const privileges_1 = require("./privileges"); | ||
const missing_privileges_error_1 = __importDefault(require("./privileges/missing-privileges-error")); | ||
/** | ||
@@ -46,2 +52,7 @@ * ---------------- | ||
function send(type, data, targetWindow) { | ||
const missingPriviliges = (0, privilege_resolver_1.sendPrivileged)(type); | ||
if (missingPriviliges !== null) { | ||
const missingPrivilegesError = new missing_privileges_error_1.default(type, missingPriviliges); | ||
return Promise.reject(missingPrivilegesError); | ||
} | ||
// Generate a unique callback ID. This here is only for simple demonstration purposes | ||
@@ -128,6 +139,16 @@ const callbackId = (0, utils_1.generateUniqueId)(); | ||
*/ | ||
function handle(type, method) { | ||
function handle(type, method, extensions) { | ||
const handleListener = function (event) { | ||
var _a; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
// Message type needs privileges to be handled | ||
if (privileges_1.ShopwareMessageTypePrivileges[type] && Object.keys(privileges_1.ShopwareMessageTypePrivileges[type]).length) { | ||
if (!extensions) { | ||
return; | ||
} | ||
const missingPrivileges = (0, privilege_resolver_1.handlePrivileged)(type, extensions, event.origin); | ||
if (missingPrivileges !== null) { | ||
return; | ||
} | ||
} | ||
if (typeof event.data !== 'string') { | ||
@@ -180,3 +201,6 @@ return; | ||
} | ||
exports.handle = handle; | ||
function handleFactory(extensions) { | ||
return (type, method) => handle(type, method, extensions); | ||
} | ||
exports.handleFactory = handleFactory; | ||
function publish(type, data) { | ||
@@ -192,3 +216,3 @@ const sendPromises = [...sourceRegistry].map((source) => { | ||
function subscribe(type, method) { | ||
return handle(type, method); | ||
return handle(type, method, {}); | ||
} | ||
@@ -211,3 +235,3 @@ exports.subscribe = subscribe; | ||
return (method) => { | ||
return handle(messageType, method); | ||
return handle(messageType, method, {}); | ||
}; | ||
@@ -241,3 +265,3 @@ } | ||
} | ||
}); | ||
}, {}); | ||
// Register at parent window | ||
@@ -244,0 +268,0 @@ yield send('__registerWindow__', {}); |
@@ -10,2 +10,5 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
(function (factory) { | ||
@@ -17,3 +20,3 @@ if (typeof module === "object" && typeof module.exports === "object") { | ||
else if (typeof define === "function" && define.amd) { | ||
define(["require", "exports", "./channel"], factory); | ||
define(["require", "exports", "./channel", "./privileges/missing-privileges-error"], factory); | ||
} | ||
@@ -24,5 +27,7 @@ })(function (require, exports) { | ||
const channel_1 = require("./channel"); | ||
const missing_privileges_error_1 = __importDefault(require("./privileges/missing-privileges-error")); | ||
describe('Test the channel bridge from iFrame to admin', () => { | ||
const defaultHandle = (0, channel_1.handleFactory)({}); | ||
it('should send "reload" command to the admin', (done) => { | ||
const removeListener = (0, channel_1.handle)('windowReload', (result) => { | ||
const removeListener = defaultHandle('windowReload', (result) => { | ||
expect(result).toEqual({}); | ||
@@ -35,3 +40,3 @@ removeListener(); | ||
it('should send "reload" command to the admin also without options', (done) => { | ||
const removeListener = (0, channel_1.handle)('windowReload', (result) => { | ||
const removeListener = defaultHandle('windowReload', (result) => { | ||
expect(result).toEqual({}); | ||
@@ -47,3 +52,3 @@ removeListener(); | ||
const PAGE_TITLE = 'Awesome page title'; | ||
const removeListener = (0, channel_1.handle)('getPageTitle', () => { | ||
const removeListener = defaultHandle('getPageTitle', () => { | ||
return PAGE_TITLE; | ||
@@ -151,4 +156,33 @@ }); | ||
})); | ||
it('should reject send with missing privileges', () => { | ||
(0, channel_1.send)('_privileges', {}).catch(e => { | ||
const expectedError = new missing_privileges_error_1.default('_privileges', ['create:user', 'read:user', 'update:user', 'delete:user']); | ||
expect(e.message).toEqual(expectedError.message); | ||
}); | ||
}); | ||
it('should not call handle callback with missing extensions', () => { | ||
const callback = jest.fn(); | ||
const removeHandle = defaultHandle('_privileges', callback); | ||
// Simulate a postMessage call from an iFrame | ||
window.dispatchEvent(new Event('message')); | ||
removeHandle(); | ||
expect(callback).toHaveBeenCalledTimes(0); | ||
}); | ||
it('should not call handle callback with missing privileges', () => { | ||
const url = 'http://example.com'; | ||
const callback = jest.fn(); | ||
const handle = (0, channel_1.handleFactory)({ foo: { baseUrl: url, permissions: { create: ['notification'] } } }); | ||
const removeHandle = handle('_privileges', callback); | ||
const event = new Event('message'); | ||
// Simulate a postMessage call from an iFrame with a none registered origin | ||
window.dispatchEvent(event); | ||
// Simulate a postMessage call from an iFrame | ||
// @ts-expect-error | ||
event.origin = url; | ||
window.dispatchEvent(event); | ||
removeHandle(); | ||
expect(callback).toHaveBeenCalledTimes(0); | ||
}); | ||
}); | ||
}); | ||
//# sourceMappingURL=channel.spec.js.map |
@@ -27,2 +27,3 @@ import { notificationDispatch } from './notification/index'; | ||
_subtract: _subtract; | ||
_privileges: _privileges; | ||
}; | ||
@@ -51,2 +52,5 @@ /** | ||
}; | ||
export declare type _privileges = { | ||
responseType: void; | ||
}; | ||
export declare type __function__ = { | ||
@@ -53,0 +57,0 @@ responseType: any; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
155887
99
2401
14