@payyo/ptp-js 2.1.1 → 2.2.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/dist/index.d.ts +1 -0
- package/dist/index.es.js +38 -5
- package/dist/index.js +38 -5
- package/package.json +1 -1
- package/src/form/form.ts +18 -4
package/dist/index.d.ts
CHANGED
package/dist/index.es.js
CHANGED
|
@@ -8,12 +8,36 @@ var FieldType = /* @__PURE__ */ ((FieldType2) => {
|
|
|
8
8
|
FieldType2["SecurityCode"] = "securityCode";
|
|
9
9
|
return FieldType2;
|
|
10
10
|
})(FieldType || {});
|
|
11
|
+
function originAllowed(origin, allowed) {
|
|
12
|
+
if (!origin) {
|
|
13
|
+
return false;
|
|
14
|
+
}
|
|
15
|
+
return allowed.includes(origin);
|
|
16
|
+
}
|
|
17
|
+
function formIdMatches(incoming, expected) {
|
|
18
|
+
if (!incoming || !expected) {
|
|
19
|
+
return false;
|
|
20
|
+
}
|
|
21
|
+
return incoming === expected;
|
|
22
|
+
}
|
|
23
|
+
function fieldOriginFrom(fieldUrl) {
|
|
24
|
+
if (!fieldUrl) {
|
|
25
|
+
return "";
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
return new URL(fieldUrl).origin;
|
|
29
|
+
} catch {
|
|
30
|
+
return "";
|
|
31
|
+
}
|
|
32
|
+
}
|
|
11
33
|
function createForm(config) {
|
|
12
34
|
const fields = {};
|
|
13
35
|
const fieldNames = [];
|
|
14
36
|
const callbacks = {};
|
|
15
37
|
const formId = generateRandomId();
|
|
16
|
-
let fieldUrl = config.fieldUrl && config.mode === Mode.Test ? config.fieldUrl : "https://cdn.ptp.payyo.ch/ptp-js/2.
|
|
38
|
+
let fieldUrl = config.fieldUrl && config.mode === Mode.Test ? config.fieldUrl : "https://cdn.ptp.payyo.ch/ptp-js/2.2.0/field.html";
|
|
39
|
+
const fieldOrigin = fieldOriginFrom(fieldUrl);
|
|
40
|
+
const sendTarget = fieldOrigin || "*";
|
|
17
41
|
const EVENT_ON_CHANGE = "change";
|
|
18
42
|
const EVENT_ON_READY = "ready";
|
|
19
43
|
const EVENT_ON_FOCUS = "focus";
|
|
@@ -37,6 +61,7 @@ function createForm(config) {
|
|
|
37
61
|
// @ts-ignore
|
|
38
62
|
src: `${fieldUrl}?${new URLSearchParams({
|
|
39
63
|
form_id: formId,
|
|
64
|
+
parent_origin: window.location.origin,
|
|
40
65
|
field_name: field.name,
|
|
41
66
|
field_type: field.type,
|
|
42
67
|
field_names: fieldNames,
|
|
@@ -74,7 +99,7 @@ function createForm(config) {
|
|
|
74
99
|
log("send message", message);
|
|
75
100
|
if (mainFieldName) {
|
|
76
101
|
const mainIFrameName = fields[mainFieldName].iFrameName;
|
|
77
|
-
window.frames[mainIFrameName].postMessage(message,
|
|
102
|
+
window.frames[mainIFrameName].postMessage(message, sendTarget);
|
|
78
103
|
}
|
|
79
104
|
});
|
|
80
105
|
}
|
|
@@ -97,7 +122,7 @@ function createForm(config) {
|
|
|
97
122
|
for (let [, field] of Object.entries(fields)) {
|
|
98
123
|
const iframe = window.frames[field.iFrameName];
|
|
99
124
|
if (iframe) {
|
|
100
|
-
iframe.postMessage({ type: "checkFocus" },
|
|
125
|
+
iframe.postMessage({ type: "checkFocus", formId }, sendTarget);
|
|
101
126
|
}
|
|
102
127
|
}
|
|
103
128
|
}
|
|
@@ -178,11 +203,12 @@ function createForm(config) {
|
|
|
178
203
|
}
|
|
179
204
|
window.frames[fields[fieldName].iFrameName].postMessage({
|
|
180
205
|
type: "setStyle",
|
|
206
|
+
formId,
|
|
181
207
|
params: {
|
|
182
208
|
selector,
|
|
183
209
|
rules: cssRules
|
|
184
210
|
}
|
|
185
|
-
},
|
|
211
|
+
}, sendTarget);
|
|
186
212
|
},
|
|
187
213
|
destroy: function() {
|
|
188
214
|
var _a;
|
|
@@ -198,9 +224,16 @@ function createForm(config) {
|
|
|
198
224
|
};
|
|
199
225
|
function receiveMessage(message) {
|
|
200
226
|
const event = message.data;
|
|
201
|
-
if (
|
|
227
|
+
if (!formIdMatches(event.formId, formId)) {
|
|
202
228
|
return;
|
|
203
229
|
}
|
|
230
|
+
if (fieldOrigin && !originAllowed(message.origin, [fieldOrigin])) {
|
|
231
|
+
log("dropping message from disallowed origin", message.origin, event);
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
if (!fieldOrigin) {
|
|
235
|
+
log("field origin unknown, skipping origin check on received message", event);
|
|
236
|
+
}
|
|
204
237
|
log(`message received of type "${event.type}"`, event);
|
|
205
238
|
const handlers2 = {
|
|
206
239
|
fieldReady: (event2) => {
|
package/dist/index.js
CHANGED
|
@@ -10,12 +10,36 @@ var FieldType = /* @__PURE__ */ ((FieldType2) => {
|
|
|
10
10
|
FieldType2["SecurityCode"] = "securityCode";
|
|
11
11
|
return FieldType2;
|
|
12
12
|
})(FieldType || {});
|
|
13
|
+
function originAllowed(origin, allowed) {
|
|
14
|
+
if (!origin) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
return allowed.includes(origin);
|
|
18
|
+
}
|
|
19
|
+
function formIdMatches(incoming, expected) {
|
|
20
|
+
if (!incoming || !expected) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
return incoming === expected;
|
|
24
|
+
}
|
|
25
|
+
function fieldOriginFrom(fieldUrl) {
|
|
26
|
+
if (!fieldUrl) {
|
|
27
|
+
return "";
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
return new URL(fieldUrl).origin;
|
|
31
|
+
} catch {
|
|
32
|
+
return "";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
13
35
|
function createForm(config) {
|
|
14
36
|
const fields = {};
|
|
15
37
|
const fieldNames = [];
|
|
16
38
|
const callbacks = {};
|
|
17
39
|
const formId = generateRandomId();
|
|
18
|
-
let fieldUrl = config.fieldUrl && config.mode === Mode.Test ? config.fieldUrl : "https://cdn.ptp.payyo.ch/ptp-js/2.
|
|
40
|
+
let fieldUrl = config.fieldUrl && config.mode === Mode.Test ? config.fieldUrl : "https://cdn.ptp.payyo.ch/ptp-js/2.2.0/field.html";
|
|
41
|
+
const fieldOrigin = fieldOriginFrom(fieldUrl);
|
|
42
|
+
const sendTarget = fieldOrigin || "*";
|
|
19
43
|
const EVENT_ON_CHANGE = "change";
|
|
20
44
|
const EVENT_ON_READY = "ready";
|
|
21
45
|
const EVENT_ON_FOCUS = "focus";
|
|
@@ -39,6 +63,7 @@ function createForm(config) {
|
|
|
39
63
|
// @ts-ignore
|
|
40
64
|
src: `${fieldUrl}?${new URLSearchParams({
|
|
41
65
|
form_id: formId,
|
|
66
|
+
parent_origin: window.location.origin,
|
|
42
67
|
field_name: field.name,
|
|
43
68
|
field_type: field.type,
|
|
44
69
|
field_names: fieldNames,
|
|
@@ -76,7 +101,7 @@ function createForm(config) {
|
|
|
76
101
|
log("send message", message);
|
|
77
102
|
if (mainFieldName) {
|
|
78
103
|
const mainIFrameName = fields[mainFieldName].iFrameName;
|
|
79
|
-
window.frames[mainIFrameName].postMessage(message,
|
|
104
|
+
window.frames[mainIFrameName].postMessage(message, sendTarget);
|
|
80
105
|
}
|
|
81
106
|
});
|
|
82
107
|
}
|
|
@@ -99,7 +124,7 @@ function createForm(config) {
|
|
|
99
124
|
for (let [, field] of Object.entries(fields)) {
|
|
100
125
|
const iframe = window.frames[field.iFrameName];
|
|
101
126
|
if (iframe) {
|
|
102
|
-
iframe.postMessage({ type: "checkFocus" },
|
|
127
|
+
iframe.postMessage({ type: "checkFocus", formId }, sendTarget);
|
|
103
128
|
}
|
|
104
129
|
}
|
|
105
130
|
}
|
|
@@ -180,11 +205,12 @@ function createForm(config) {
|
|
|
180
205
|
}
|
|
181
206
|
window.frames[fields[fieldName].iFrameName].postMessage({
|
|
182
207
|
type: "setStyle",
|
|
208
|
+
formId,
|
|
183
209
|
params: {
|
|
184
210
|
selector,
|
|
185
211
|
rules: cssRules
|
|
186
212
|
}
|
|
187
|
-
},
|
|
213
|
+
}, sendTarget);
|
|
188
214
|
},
|
|
189
215
|
destroy: function() {
|
|
190
216
|
var _a;
|
|
@@ -200,9 +226,16 @@ function createForm(config) {
|
|
|
200
226
|
};
|
|
201
227
|
function receiveMessage(message) {
|
|
202
228
|
const event = message.data;
|
|
203
|
-
if (
|
|
229
|
+
if (!formIdMatches(event.formId, formId)) {
|
|
204
230
|
return;
|
|
205
231
|
}
|
|
232
|
+
if (fieldOrigin && !originAllowed(message.origin, [fieldOrigin])) {
|
|
233
|
+
log("dropping message from disallowed origin", message.origin, event);
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
if (!fieldOrigin) {
|
|
237
|
+
log("field origin unknown, skipping origin check on received message", event);
|
|
238
|
+
}
|
|
206
239
|
log(`message received of type "${event.type}"`, event);
|
|
207
240
|
const handlers2 = {
|
|
208
241
|
fieldReady: (event2) => {
|
package/package.json
CHANGED
package/src/form/form.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {Field, FieldEvent, Form, FormConfig, Message, MessageResponse, Mode, SetStyleEvent} from "../types.ts";
|
|
2
|
+
import {fieldOriginFrom, formIdMatches, originAllowed} from "../messaging.ts";
|
|
2
3
|
|
|
3
4
|
export function createForm(config: FormConfig): Form {
|
|
4
5
|
const fields: Record<string, Field> = {};
|
|
@@ -8,6 +9,9 @@ export function createForm(config: FormConfig): Form {
|
|
|
8
9
|
|
|
9
10
|
let fieldUrl = (config.fieldUrl && config.mode === Mode.Test) ? config.fieldUrl : import.meta.env.VITE_PTP_FIELD_URL;
|
|
10
11
|
|
|
12
|
+
const fieldOrigin = fieldOriginFrom(fieldUrl);
|
|
13
|
+
const sendTarget = fieldOrigin || '*';
|
|
14
|
+
|
|
11
15
|
const EVENT_ON_CHANGE = 'change';
|
|
12
16
|
const EVENT_ON_READY = 'ready';
|
|
13
17
|
const EVENT_ON_FOCUS = 'focus';
|
|
@@ -37,6 +41,7 @@ export function createForm(config: FormConfig): Form {
|
|
|
37
41
|
// @ts-ignore
|
|
38
42
|
src: `${fieldUrl}?${(new URLSearchParams({
|
|
39
43
|
form_id: formId,
|
|
44
|
+
parent_origin: window.location.origin,
|
|
40
45
|
field_name: field.name,
|
|
41
46
|
field_type: field.type,
|
|
42
47
|
field_names: fieldNames,
|
|
@@ -83,7 +88,7 @@ export function createForm(config: FormConfig): Form {
|
|
|
83
88
|
if (mainFieldName) {
|
|
84
89
|
const mainIFrameName = fields[mainFieldName].iFrameName;
|
|
85
90
|
// @ts-ignore
|
|
86
|
-
window.frames[mainIFrameName].postMessage(message,
|
|
91
|
+
window.frames[mainIFrameName].postMessage(message, sendTarget);
|
|
87
92
|
}
|
|
88
93
|
});
|
|
89
94
|
}
|
|
@@ -112,7 +117,7 @@ export function createForm(config: FormConfig): Form {
|
|
|
112
117
|
// @ts-ignore
|
|
113
118
|
const iframe = window.frames[field.iFrameName];
|
|
114
119
|
if (iframe) {
|
|
115
|
-
iframe.postMessage({type: 'checkFocus'},
|
|
120
|
+
iframe.postMessage({type: 'checkFocus', formId: formId}, sendTarget);
|
|
116
121
|
}
|
|
117
122
|
}
|
|
118
123
|
}
|
|
@@ -204,11 +209,12 @@ export function createForm(config: FormConfig): Form {
|
|
|
204
209
|
// @ts-ignore
|
|
205
210
|
window.frames[fields[fieldName].iFrameName].postMessage({
|
|
206
211
|
type: 'setStyle',
|
|
212
|
+
formId: formId,
|
|
207
213
|
params: {
|
|
208
214
|
selector: selector,
|
|
209
215
|
rules: cssRules,
|
|
210
216
|
} as SetStyleEvent
|
|
211
|
-
},
|
|
217
|
+
}, sendTarget);
|
|
212
218
|
},
|
|
213
219
|
destroy: function () {
|
|
214
220
|
window.removeEventListener('message', receiveMessage, false);
|
|
@@ -224,10 +230,18 @@ export function createForm(config: FormConfig): Form {
|
|
|
224
230
|
|
|
225
231
|
function receiveMessage(message: MessageEvent<Message>) {
|
|
226
232
|
const event: Message = message.data;
|
|
227
|
-
if (
|
|
233
|
+
if (!formIdMatches(event.formId, formId)) {
|
|
228
234
|
return;
|
|
229
235
|
}
|
|
230
236
|
|
|
237
|
+
if (fieldOrigin && !originAllowed(message.origin, [fieldOrigin])) {
|
|
238
|
+
log('dropping message from disallowed origin', message.origin, event);
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
if (!fieldOrigin) {
|
|
242
|
+
log('field origin unknown, skipping origin check on received message', event);
|
|
243
|
+
}
|
|
244
|
+
|
|
231
245
|
log(`message received of type "${event.type}"`, event);
|
|
232
246
|
|
|
233
247
|
const handlers: Record<string, Function> = {
|