@atlasauth/emulator-core 0.2.0 → 0.3.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/custom-html.d.ts +57 -0
- package/dist/custom-html.js +491 -0
- package/dist/custom-html.js.map +1 -0
- package/dist/engine.d.ts +1 -1
- package/dist/engine.js +4 -0
- package/dist/engine.js.map +1 -1
- package/dist/error-catalog.js +8 -0
- package/dist/error-catalog.js.map +1 -1
- package/dist/event-gate.js +60 -2
- package/dist/event-gate.js.map +1 -1
- package/dist/generic.js +5 -1
- package/dist/generic.js.map +1 -1
- package/dist/handlers/access-signals.d.ts +48 -0
- package/dist/handlers/access-signals.js +76 -0
- package/dist/handlers/access-signals.js.map +1 -0
- package/dist/handlers/approvals.js +54 -1
- package/dist/handlers/approvals.js.map +1 -1
- package/dist/handlers/authz-data.d.ts +2 -0
- package/dist/handlers/authz-data.js +627 -0
- package/dist/handlers/authz-data.js.map +1 -0
- package/dist/handlers/authz-layers.d.ts +229 -0
- package/dist/handlers/authz-layers.js +786 -0
- package/dist/handlers/authz-layers.js.map +1 -0
- package/dist/handlers/authz-state.d.ts +80 -0
- package/dist/handlers/authz-state.js +175 -0
- package/dist/handlers/authz-state.js.map +1 -0
- package/dist/handlers/authz.js +240 -177
- package/dist/handlers/authz.js.map +1 -1
- package/dist/handlers/billing.d.ts +99 -1
- package/dist/handlers/billing.js +556 -77
- package/dist/handlers/billing.js.map +1 -1
- package/dist/handlers/cedar-ext.d.ts +35 -0
- package/dist/handlers/cedar-ext.js +174 -0
- package/dist/handlers/cedar-ext.js.map +1 -0
- package/dist/handlers/cedar.d.ts +146 -0
- package/dist/handlers/cedar.js +689 -0
- package/dist/handlers/cedar.js.map +1 -0
- package/dist/handlers/connections.d.ts +4 -1
- package/dist/handlers/connections.js +267 -38
- package/dist/handlers/connections.js.map +1 -1
- package/dist/handlers/control.js +6 -1
- package/dist/handlers/control.js.map +1 -1
- package/dist/handlers/device.js +18 -1
- package/dist/handlers/device.js.map +1 -1
- package/dist/handlers/emu3-misc.d.ts +38 -0
- package/dist/handlers/emu3-misc.js +1056 -0
- package/dist/handlers/emu3-misc.js.map +1 -0
- package/dist/handlers/emu4-actions-access.d.ts +46 -0
- package/dist/handlers/emu4-actions-access.js +107 -0
- package/dist/handlers/emu4-actions-access.js.map +1 -0
- package/dist/handlers/emu4-actions-catalog-extra.d.ts +3 -0
- package/dist/handlers/emu4-actions-catalog-extra.js +204 -0
- package/dist/handlers/emu4-actions-catalog-extra.js.map +1 -0
- package/dist/handlers/emu4-actions-catalog.d.ts +3 -0
- package/dist/handlers/emu4-actions-catalog.js +143 -0
- package/dist/handlers/emu4-actions-catalog.js.map +1 -0
- package/dist/handlers/emu4-actions-def.d.ts +50 -0
- package/dist/handlers/emu4-actions-def.js +250 -0
- package/dist/handlers/emu4-actions-def.js.map +1 -0
- package/dist/handlers/emu4-actions-sandbox.d.ts +36 -0
- package/dist/handlers/emu4-actions-sandbox.js +318 -0
- package/dist/handlers/emu4-actions-sandbox.js.map +1 -0
- package/dist/handlers/emu4-actions-typegen.d.ts +5 -0
- package/dist/handlers/emu4-actions-typegen.js +73 -0
- package/dist/handlers/emu4-actions-typegen.js.map +1 -0
- package/dist/handlers/emu4-actions.d.ts +2 -0
- package/dist/handlers/emu4-actions.js +506 -0
- package/dist/handlers/emu4-actions.js.map +1 -0
- package/dist/handlers/emu4-authz-trust.d.ts +40 -0
- package/dist/handlers/emu4-authz-trust.js +488 -0
- package/dist/handlers/emu4-authz-trust.js.map +1 -0
- package/dist/handlers/emu4-authz.d.ts +2 -0
- package/dist/handlers/emu4-authz.js +752 -0
- package/dist/handlers/emu4-authz.js.map +1 -0
- package/dist/handlers/emu4-billing-core.d.ts +23 -0
- package/dist/handlers/emu4-billing-core.js +22 -0
- package/dist/handlers/emu4-billing-core.js.map +1 -0
- package/dist/handlers/emu4-billing-x.d.ts +2 -0
- package/dist/handlers/emu4-billing-x.js +489 -0
- package/dist/handlers/emu4-billing-x.js.map +1 -0
- package/dist/handlers/emu4-billing.d.ts +14 -0
- package/dist/handlers/emu4-billing.js +846 -0
- package/dist/handlers/emu4-billing.js.map +1 -0
- package/dist/handlers/emu4-clones.d.ts +2 -0
- package/dist/handlers/emu4-clones.js +322 -0
- package/dist/handlers/emu4-clones.js.map +1 -0
- package/dist/handlers/emu4-compliance.d.ts +8 -0
- package/dist/handlers/emu4-compliance.js +39 -0
- package/dist/handlers/emu4-compliance.js.map +1 -0
- package/dist/handlers/emu4-config.d.ts +14 -0
- package/dist/handlers/emu4-config.js +148 -0
- package/dist/handlers/emu4-config.js.map +1 -0
- package/dist/handlers/emu4-cookies.d.ts +8 -0
- package/dist/handlers/emu4-cookies.js +248 -0
- package/dist/handlers/emu4-cookies.js.map +1 -0
- package/dist/handlers/emu4-erasure.d.ts +2 -0
- package/dist/handlers/emu4-erasure.js +587 -0
- package/dist/handlers/emu4-erasure.js.map +1 -0
- package/dist/handlers/emu4-federation.d.ts +8 -0
- package/dist/handlers/emu4-federation.js +18 -0
- package/dist/handlers/emu4-federation.js.map +1 -0
- package/dist/handlers/emu4-journey-math.d.ts +42 -0
- package/dist/handlers/emu4-journey-math.js +99 -0
- package/dist/handlers/emu4-journey-math.js.map +1 -0
- package/dist/handlers/emu4-messaging.d.ts +21 -0
- package/dist/handlers/emu4-messaging.js +595 -0
- package/dist/handlers/emu4-messaging.js.map +1 -0
- package/dist/handlers/emu4-minors.d.ts +7 -0
- package/dist/handlers/emu4-minors.js +408 -0
- package/dist/handlers/emu4-minors.js.map +1 -0
- package/dist/handlers/emu4-oauth-audit.d.ts +5 -0
- package/dist/handlers/emu4-oauth-audit.js +17 -0
- package/dist/handlers/emu4-oauth-audit.js.map +1 -0
- package/dist/handlers/emu4-oauth-auth.d.ts +83 -0
- package/dist/handlers/emu4-oauth-auth.js +363 -0
- package/dist/handlers/emu4-oauth-auth.js.map +1 -0
- package/dist/handlers/emu4-oauth-delivery.d.ts +68 -0
- package/dist/handlers/emu4-oauth-delivery.js +207 -0
- package/dist/handlers/emu4-oauth-delivery.js.map +1 -0
- package/dist/handlers/emu4-oauth-keys.d.ts +11 -0
- package/dist/handlers/emu4-oauth-keys.js +268 -0
- package/dist/handlers/emu4-oauth-keys.js.map +1 -0
- package/dist/handlers/emu4-oauth-pub.d.ts +36 -0
- package/dist/handlers/emu4-oauth-pub.js +420 -0
- package/dist/handlers/emu4-oauth-pub.js.map +1 -0
- package/dist/handlers/emu4-oauth.d.ts +10 -0
- package/dist/handlers/emu4-oauth.js +23 -0
- package/dist/handlers/emu4-oauth.js.map +1 -0
- package/dist/handlers/emu4-policies.d.ts +2 -0
- package/dist/handlers/emu4-policies.js +408 -0
- package/dist/handlers/emu4-policies.js.map +1 -0
- package/dist/handlers/emu4-region.d.ts +2 -0
- package/dist/handlers/emu4-region.js +189 -0
- package/dist/handlers/emu4-region.js.map +1 -0
- package/dist/handlers/emu4-saml.d.ts +12 -0
- package/dist/handlers/emu4-saml.js +532 -0
- package/dist/handlers/emu4-saml.js.map +1 -0
- package/dist/handlers/emu4-shared.d.ts +44 -0
- package/dist/handlers/emu4-shared.js +90 -0
- package/dist/handlers/emu4-shared.js.map +1 -0
- package/dist/handlers/emu4-snapshots.d.ts +38 -0
- package/dist/handlers/emu4-snapshots.js +231 -0
- package/dist/handlers/emu4-snapshots.js.map +1 -0
- package/dist/handlers/emu4-sns.d.ts +9 -0
- package/dist/handlers/emu4-sns.js +21 -0
- package/dist/handlers/emu4-sns.js.map +1 -0
- package/dist/handlers/emu4-trust-binding.d.ts +27 -0
- package/dist/handlers/emu4-trust-binding.js +344 -0
- package/dist/handlers/emu4-trust-binding.js.map +1 -0
- package/dist/handlers/emu4-trust.d.ts +35 -0
- package/dist/handlers/emu4-trust.js +543 -0
- package/dist/handlers/emu4-trust.js.map +1 -0
- package/dist/handlers/fga-engine.d.ts +78 -0
- package/dist/handlers/fga-engine.js +663 -0
- package/dist/handlers/fga-engine.js.map +1 -0
- package/dist/handlers/hooks.js +13 -0
- package/dist/handlers/hooks.js.map +1 -1
- package/dist/handlers/index.js +14 -1
- package/dist/handlers/index.js.map +1 -1
- package/dist/handlers/machines.js +6 -0
- package/dist/handlers/machines.js.map +1 -1
- package/dist/handlers/messaging.d.ts +3 -1
- package/dist/handlers/messaging.js +455 -48
- package/dist/handlers/messaging.js.map +1 -1
- package/dist/handlers/oauth-adv.d.ts +191 -0
- package/dist/handlers/oauth-adv.js +1305 -0
- package/dist/handlers/oauth-adv.js.map +1 -0
- package/dist/handlers/oauth-flows.d.ts +25 -1
- package/dist/handlers/oauth-flows.js +111 -50
- package/dist/handlers/oauth-flows.js.map +1 -1
- package/dist/handlers/oauth.d.ts +24 -3
- package/dist/handlers/oauth.js +245 -60
- package/dist/handlers/oauth.js.map +1 -1
- package/dist/handlers/orgs.js +6 -0
- package/dist/handlers/orgs.js.map +1 -1
- package/dist/handlers/platform.d.ts +5 -0
- package/dist/handlers/platform.js +33 -15
- package/dist/handlers/platform.js.map +1 -1
- package/dist/handlers/scim.d.ts +2 -0
- package/dist/handlers/scim.js +198 -11
- package/dist/handlers/scim.js.map +1 -1
- package/dist/handlers/sessions.d.ts +2 -0
- package/dist/handlers/sessions.js +24 -16
- package/dist/handlers/sessions.js.map +1 -1
- package/dist/handlers/users.js +3 -0
- package/dist/handlers/users.js.map +1 -1
- package/dist/jwe.d.ts +18 -0
- package/dist/jwe.js +101 -0
- package/dist/jwe.js.map +1 -0
- package/dist/jws.js +2 -0
- package/dist/jws.js.map +1 -1
- package/dist/messaging-callbacks.d.ts +100 -0
- package/dist/messaging-callbacks.js +767 -0
- package/dist/messaging-callbacks.js.map +1 -0
- package/dist/openapi.js +41 -1
- package/dist/openapi.js.map +1 -1
- package/dist/parity-emu3-authz.d.ts +3 -0
- package/dist/parity-emu3-authz.js +61 -0
- package/dist/parity-emu3-authz.js.map +1 -0
- package/dist/parity-emu3-billing.d.ts +3 -0
- package/dist/parity-emu3-billing.js +25 -0
- package/dist/parity-emu3-billing.js.map +1 -0
- package/dist/parity-emu3-messaging.d.ts +3 -0
- package/dist/parity-emu3-messaging.js +27 -0
- package/dist/parity-emu3-messaging.js.map +1 -0
- package/dist/parity-emu3-misc.d.ts +2 -0
- package/dist/parity-emu3-misc.js +63 -0
- package/dist/parity-emu3-misc.js.map +1 -0
- package/dist/parity-emu3-oauth.d.ts +2 -0
- package/dist/parity-emu3-oauth.js +39 -0
- package/dist/parity-emu3-oauth.js.map +1 -0
- package/dist/parity-emu4-actions.d.ts +2 -0
- package/dist/parity-emu4-actions.js +38 -0
- package/dist/parity-emu4-actions.js.map +1 -0
- package/dist/parity-emu4-authz.d.ts +3 -0
- package/dist/parity-emu4-authz.js +68 -0
- package/dist/parity-emu4-authz.js.map +1 -0
- package/dist/parity-emu4-billing.d.ts +6 -0
- package/dist/parity-emu4-billing.js +44 -0
- package/dist/parity-emu4-billing.js.map +1 -0
- package/dist/parity-emu4-compliance.d.ts +2 -0
- package/dist/parity-emu4-compliance.js +92 -0
- package/dist/parity-emu4-compliance.js.map +1 -0
- package/dist/parity-emu4-federation.d.ts +2 -0
- package/dist/parity-emu4-federation.js +33 -0
- package/dist/parity-emu4-federation.js.map +1 -0
- package/dist/parity-emu4-messaging.d.ts +3 -0
- package/dist/parity-emu4-messaging.js +42 -0
- package/dist/parity-emu4-messaging.js.map +1 -0
- package/dist/parity-emu4-oauth.d.ts +2 -0
- package/dist/parity-emu4-oauth.js +55 -0
- package/dist/parity-emu4-oauth.js.map +1 -0
- package/dist/parity-emu4-trust.d.ts +2 -0
- package/dist/parity-emu4-trust.js +41 -0
- package/dist/parity-emu4-trust.js.map +1 -0
- package/dist/parity-routes.js +19 -1
- package/dist/parity-routes.js.map +1 -1
- package/dist/sns-cert.d.ts +9 -0
- package/dist/sns-cert.js +101 -0
- package/dist/sns-cert.js.map +1 -0
- package/dist/tokens.d.ts +69 -4
- package/dist/tokens.js +164 -38
- package/dist/tokens.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,318 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.actionRuns = exports.isRuntimeForm = exports.sandboxAvailable = exports.ACTION_TIMEOUT_MS = void 0;
|
|
4
|
+
exports.runActionCode = runActionCode;
|
|
5
|
+
const store_1 = require("../store");
|
|
6
|
+
const support_1 = require("./support");
|
|
7
|
+
/**
|
|
8
|
+
* The Action runtime the emulator runs, on node:vm. The in-sandbox bootstrap below is the real runtime's `api` object (same
|
|
9
|
+
* names, limits and truncations); only the host side differs: a fresh vm context with no globals beyond the language's own
|
|
10
|
+
* (no require, process, fetch, timers or console), code generation from strings disabled, the event handed over as a JSON
|
|
11
|
+
* string parsed inside the context, a CPU timeout, and the result read back as a string. Nothing from the host is reachable.
|
|
12
|
+
*/
|
|
13
|
+
const ACTION_HTTP_LIMITS = { perAction: 5, perFlow: 10, urlMax: 2048, headersMax: 20, headerValueMax: 4096, bodyMax: 64 * 1024 };
|
|
14
|
+
const ACTION_CONNECTOR_LIMITS = { perAction: 5, perFlow: 10, inputMax: 16 * 1024 };
|
|
15
|
+
const BOOTSTRAP = `
|
|
16
|
+
'use strict';
|
|
17
|
+
function __atlasDeepFreeze(o) {
|
|
18
|
+
if (o && typeof o === 'object') {
|
|
19
|
+
for (const k of Object.getOwnPropertyNames(o)) {
|
|
20
|
+
try { __atlasDeepFreeze(o[k]); } catch (e) { /* getter, skip */ }
|
|
21
|
+
}
|
|
22
|
+
Object.freeze(o);
|
|
23
|
+
}
|
|
24
|
+
return o;
|
|
25
|
+
}
|
|
26
|
+
const event = __atlasDeepFreeze(globalThis.__atlas_event_raw);
|
|
27
|
+
try { delete globalThis.__atlas_event_raw; } catch (e) {}
|
|
28
|
+
const __atlas_result = {
|
|
29
|
+
accessTokenClaims: {}, idTokenClaims: {}, appMetadata: {}, sessionData: {},
|
|
30
|
+
externalIdSet: false, externalId: null,
|
|
31
|
+
denied: false, denyReason: null, logs: [], http: [], connectorCalls: [], error: null,
|
|
32
|
+
lockReason: null, pauseReason: null, suppressedAccessClaims: [], suppressedIdClaims: [],
|
|
33
|
+
userEdits: {}, signUpPrefill: {}, signUpModify: {}, challenge: null, challengeAccept: null, exchangeSubject: null, messageRewrite: null,
|
|
34
|
+
};
|
|
35
|
+
function __atlasStr(v, max) { return v == null ? null : (String(v).trim().slice(0, max) || null); }
|
|
36
|
+
function __atlasClaimKey(k) { return String(k).slice(0, 256); }
|
|
37
|
+
var __ATLAS_HTTP_FORBIDDEN = ['host', 'content-length', 'connection', 'transfer-encoding', 'upgrade', 'te', 'trailer', 'keep-alive', 'proxy-authorization', 'proxy-connection', 'expect'];
|
|
38
|
+
function __atlasHttp(method, url, options) {
|
|
39
|
+
options = options || {};
|
|
40
|
+
if (__atlas_result.http.length >= ${ACTION_HTTP_LIMITS.perAction}) {
|
|
41
|
+
throw new RangeError('api.http: at most ${ACTION_HTTP_LIMITS.perAction} requests per action run');
|
|
42
|
+
}
|
|
43
|
+
url = String(url);
|
|
44
|
+
if (!/^https:\\/\\/[^\\s]+$/i.test(url) || url.length > ${ACTION_HTTP_LIMITS.urlMax}) {
|
|
45
|
+
throw new TypeError('api.http: the url must be an https:// URL of at most ${ACTION_HTTP_LIMITS.urlMax} characters');
|
|
46
|
+
}
|
|
47
|
+
var headers = {};
|
|
48
|
+
var lower = {};
|
|
49
|
+
if (options.headers != null) {
|
|
50
|
+
if (typeof options.headers !== 'object' || Array.isArray(options.headers)) throw new TypeError('api.http: headers must be an object');
|
|
51
|
+
var names = Object.keys(options.headers);
|
|
52
|
+
if (names.length > ${ACTION_HTTP_LIMITS.headersMax}) throw new RangeError('api.http: at most ${ACTION_HTTP_LIMITS.headersMax} headers');
|
|
53
|
+
for (var i = 0; i < names.length; i++) {
|
|
54
|
+
var name = names[i];
|
|
55
|
+
if (!/^[A-Za-z0-9-]{1,64}$/.test(name)) throw new TypeError('api.http: invalid header name ' + name);
|
|
56
|
+
if (__ATLAS_HTTP_FORBIDDEN.indexOf(name.toLowerCase()) >= 0) throw new TypeError('api.http: the ' + name + ' header is set by Atlas');
|
|
57
|
+
var value = String(options.headers[name]);
|
|
58
|
+
if (value.length > ${ACTION_HTTP_LIMITS.headerValueMax} || /[\\r\\n]/.test(value)) throw new TypeError('api.http: invalid value for header ' + name);
|
|
59
|
+
headers[name] = value;
|
|
60
|
+
lower[name.toLowerCase()] = true;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
var body = null;
|
|
64
|
+
if (options.body !== undefined && options.body !== null) {
|
|
65
|
+
if (method === 'GET') throw new TypeError('api.http.get: a GET request has no body');
|
|
66
|
+
body = typeof options.body === 'string' ? options.body : JSON.stringify(options.body);
|
|
67
|
+
if (typeof options.body !== 'string' && !lower['content-type']) headers['content-type'] = 'application/json';
|
|
68
|
+
if (body.length > ${ACTION_HTTP_LIMITS.bodyMax}) throw new RangeError('api.http: the body is over ${ACTION_HTTP_LIMITS.bodyMax} bytes');
|
|
69
|
+
}
|
|
70
|
+
var saveAs = null;
|
|
71
|
+
if (options.saveResponseAs != null) {
|
|
72
|
+
saveAs = String(options.saveResponseAs);
|
|
73
|
+
if (!/^[A-Za-z][A-Za-z0-9_]{0,63}$/.test(saveAs)) throw new TypeError('api.http: saveResponseAs must be a metadata key (letters, digits, _)');
|
|
74
|
+
}
|
|
75
|
+
__atlas_result.http.push({ method: method, url: url, headers: headers, body: body, saveResponseAs: saveAs });
|
|
76
|
+
}
|
|
77
|
+
function __atlasConnectorSend(name, operation, input) {
|
|
78
|
+
if (__atlas_result.connectorCalls.length >= ${ACTION_CONNECTOR_LIMITS.perAction}) {
|
|
79
|
+
throw new RangeError('api.connector.send: at most ${ACTION_CONNECTOR_LIMITS.perAction} calls per action run');
|
|
80
|
+
}
|
|
81
|
+
name = String(name); operation = String(operation);
|
|
82
|
+
if (!/^[a-z0-9][a-z0-9_-]{0,62}$/.test(name)) throw new TypeError('api.connector.send: name is the connector name you gave it');
|
|
83
|
+
if (!/^[a-z_]{1,64}$/.test(operation)) throw new TypeError('api.connector.send: operation is an operation of the connector, e.g. send_sms');
|
|
84
|
+
if (input == null) input = {};
|
|
85
|
+
if (typeof input !== 'object' || Array.isArray(input)) throw new TypeError('api.connector.send: input must be an object');
|
|
86
|
+
if (JSON.stringify(input).length > ${ACTION_CONNECTOR_LIMITS.inputMax}) throw new RangeError('api.connector.send: input is over ${ACTION_CONNECTOR_LIMITS.inputMax} bytes');
|
|
87
|
+
__atlas_result.connectorCalls.push({ name: name, operation: operation, input: JSON.parse(JSON.stringify(input)) });
|
|
88
|
+
}
|
|
89
|
+
const api = Object.freeze({
|
|
90
|
+
connector: Object.freeze({ send: function (name, operation, input) { __atlasConnectorSend(name, operation, input); } }),
|
|
91
|
+
access: Object.freeze({
|
|
92
|
+
deny: function (reason) {
|
|
93
|
+
__atlas_result.denied = true;
|
|
94
|
+
__atlas_result.denyReason = (reason == null ? 'Access denied.' : String(reason)).slice(0, 512);
|
|
95
|
+
},
|
|
96
|
+
lock: function (reason) {
|
|
97
|
+
__atlas_result.lockReason = (reason == null ? 'Account locked.' : String(reason)).slice(0, 512);
|
|
98
|
+
},
|
|
99
|
+
pause: function (reason) {
|
|
100
|
+
__atlas_result.pauseReason = (reason == null ? 'Confirm the deletion to continue.' : String(reason)).slice(0, 512);
|
|
101
|
+
},
|
|
102
|
+
}),
|
|
103
|
+
exchange: Object.freeze({
|
|
104
|
+
setUserById: function (id) {
|
|
105
|
+
__atlas_result.exchangeSubject = { by: 'id', value: String(id).trim().slice(0, 255), create: false };
|
|
106
|
+
},
|
|
107
|
+
setUserByEmail: function (email, o) {
|
|
108
|
+
o = o || {};
|
|
109
|
+
__atlas_result.exchangeSubject = { by: 'email', value: String(email).trim().toLowerCase().slice(0, 320), create: o.create === true,
|
|
110
|
+
externalId: o.externalId == null ? undefined : String(o.externalId).trim().slice(0, 255), emailVerified: o.emailVerified === true };
|
|
111
|
+
},
|
|
112
|
+
setUserByExternalId: function (externalId, o) {
|
|
113
|
+
o = o || {};
|
|
114
|
+
__atlas_result.exchangeSubject = { by: 'external_id', value: String(externalId).trim().slice(0, 255), create: o.create === true,
|
|
115
|
+
email: o.email == null ? undefined : String(o.email).trim().toLowerCase().slice(0, 320), emailVerified: o.emailVerified === true };
|
|
116
|
+
},
|
|
117
|
+
}),
|
|
118
|
+
message: Object.freeze({
|
|
119
|
+
rewrite: function (c) {
|
|
120
|
+
if (c == null || typeof c !== 'object') throw new TypeError('api.message.rewrite: an object is required');
|
|
121
|
+
var vars = {};
|
|
122
|
+
if (c.variables != null) {
|
|
123
|
+
if (typeof c.variables !== 'object' || Array.isArray(c.variables)) throw new TypeError('api.message.rewrite: variables must be an object');
|
|
124
|
+
Object.keys(c.variables).slice(0, 50).forEach(function (k) { vars[String(k).slice(0, 64)] = String(c.variables[k]).slice(0, 2000); });
|
|
125
|
+
}
|
|
126
|
+
var out = { variables: vars };
|
|
127
|
+
if (c.subject != null) out.subject = String(c.subject).slice(0, 500);
|
|
128
|
+
if (c.text != null) out.text = String(c.text).slice(0, 20000);
|
|
129
|
+
__atlas_result.messageRewrite = out;
|
|
130
|
+
},
|
|
131
|
+
}),
|
|
132
|
+
challenge: Object.freeze({
|
|
133
|
+
set: function (c) {
|
|
134
|
+
if (c == null || typeof c !== 'object' || typeof c.prompt !== 'string' || !c.prompt) throw new TypeError('api.challenge.set: a { prompt } string is required');
|
|
135
|
+
var state = c.state === undefined ? null : c.state;
|
|
136
|
+
if (JSON.stringify(state === null ? 'x' : state).length > 2048) throw new RangeError('api.challenge.set: state is over 2048 bytes');
|
|
137
|
+
__atlas_result.challenge = { prompt: c.prompt.slice(0, 512), hint: c.hint == null ? null : String(c.hint).slice(0, 256), state: state };
|
|
138
|
+
},
|
|
139
|
+
accept: function (o) {
|
|
140
|
+
var amr = o && Array.isArray(o.amr) ? o.amr.slice(0, 5).map(function (a) { return String(a).slice(0, 32); }) : ['custom'];
|
|
141
|
+
__atlas_result.challengeAccept = { amr: amr };
|
|
142
|
+
},
|
|
143
|
+
}),
|
|
144
|
+
accessToken: Object.freeze({
|
|
145
|
+
setCustomClaim: function (k, v) { __atlas_result.accessTokenClaims[__atlasClaimKey(k)] = v; },
|
|
146
|
+
suppressClaim: function (k) { if (__atlas_result.suppressedAccessClaims.length < 50) __atlas_result.suppressedAccessClaims.push(__atlasClaimKey(k)); },
|
|
147
|
+
}),
|
|
148
|
+
idToken: Object.freeze({
|
|
149
|
+
setCustomClaim: function (k, v) { __atlas_result.idTokenClaims[__atlasClaimKey(k)] = v; },
|
|
150
|
+
suppressClaim: function (k) { if (__atlas_result.suppressedIdClaims.length < 50) __atlas_result.suppressedIdClaims.push(__atlasClaimKey(k)); },
|
|
151
|
+
}),
|
|
152
|
+
signUp: Object.freeze({
|
|
153
|
+
prefill: function (k, v) { __atlas_result.signUpPrefill[__atlasClaimKey(k)] = String(v).slice(0, 1024); },
|
|
154
|
+
modify: function (k, v) { __atlas_result.signUpModify[__atlasClaimKey(k)] = String(v).slice(0, 1024); },
|
|
155
|
+
}),
|
|
156
|
+
session: Object.freeze({
|
|
157
|
+
setCustomData: function (k, v) { __atlas_result.sessionData[String(k).slice(0, 64)] = v; },
|
|
158
|
+
}),
|
|
159
|
+
user: Object.freeze({
|
|
160
|
+
setAppMetadata: function (k, v) { __atlas_result.appMetadata[__atlasClaimKey(k)] = v; },
|
|
161
|
+
setBanned: function (banned, reason) {
|
|
162
|
+
__atlas_result.userEdits.banned = { value: banned === true, reason: __atlasStr(reason, 512) };
|
|
163
|
+
},
|
|
164
|
+
setEmailVerified: function (verified) { __atlas_result.userEdits.emailVerified = verified === true; },
|
|
165
|
+
setName: function (first, last) {
|
|
166
|
+
if (first !== undefined) __atlas_result.userEdits.firstName = __atlasStr(first, 255);
|
|
167
|
+
if (last !== undefined) __atlas_result.userEdits.lastName = __atlasStr(last, 255);
|
|
168
|
+
},
|
|
169
|
+
setImage: function (url) {
|
|
170
|
+
var u = __atlasStr(url, 2048);
|
|
171
|
+
if (u !== null && !/^https:\\/\\/[^\\s]+$/i.test(u)) throw new TypeError('api.user.setImage: the url must be an https:// URL');
|
|
172
|
+
__atlas_result.userEdits.imageUrl = u;
|
|
173
|
+
},
|
|
174
|
+
setExternalId: function (id) {
|
|
175
|
+
__atlas_result.externalIdSet = true;
|
|
176
|
+
__atlas_result.externalId = id == null ? null : String(id).trim().slice(0, 255) || null;
|
|
177
|
+
},
|
|
178
|
+
}),
|
|
179
|
+
http: Object.freeze({
|
|
180
|
+
get: function (url, options) { __atlasHttp('GET', url, options); },
|
|
181
|
+
post: function (url, body, options) {
|
|
182
|
+
var o = {};
|
|
183
|
+
if (options) { for (var k in options) { if (Object.prototype.hasOwnProperty.call(options, k)) o[k] = options[k]; } }
|
|
184
|
+
o.body = body;
|
|
185
|
+
__atlasHttp('POST', url, o);
|
|
186
|
+
},
|
|
187
|
+
}),
|
|
188
|
+
console: Object.freeze({
|
|
189
|
+
log: function () {
|
|
190
|
+
var parts = Array.prototype.slice.call(arguments).map(function (a) {
|
|
191
|
+
try { return typeof a === 'string' ? a : JSON.stringify(a); } catch (e) { return String(a); }
|
|
192
|
+
});
|
|
193
|
+
if (__atlas_result.logs.length < 100) __atlas_result.logs.push(parts.join(' ').slice(0, 2000));
|
|
194
|
+
},
|
|
195
|
+
}),
|
|
196
|
+
});
|
|
197
|
+
`;
|
|
198
|
+
/** Timeout of one Action run, in CPU milliseconds (the real service allows 2 s; the emulator keeps a test suite fast). */
|
|
199
|
+
exports.ACTION_TIMEOUT_MS = 100;
|
|
200
|
+
const MAX_OUT = 1_000_000;
|
|
201
|
+
const vmModule = () => {
|
|
202
|
+
try {
|
|
203
|
+
return process.getBuiltinModule?.('node:vm') ?? null;
|
|
204
|
+
}
|
|
205
|
+
catch {
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
/** True when the emulator can run Action code (Node 22+); false in a browser, where the declarative reader is used. */
|
|
210
|
+
const sandboxAvailable = () => vmModule() !== null;
|
|
211
|
+
exports.sandboxAvailable = sandboxAvailable;
|
|
212
|
+
/** Code written as a handler module (`exports.onExecute...`, `module.exports`) is not the runtime's form: the caller reads it declaratively. */
|
|
213
|
+
const isRuntimeForm = (code) => !/\b(?:module\.exports|exports\.on[A-Z]\w*)\b/.test(code);
|
|
214
|
+
exports.isRuntimeForm = isRuntimeForm;
|
|
215
|
+
const obj = (v) => (v && typeof v === 'object' && !Array.isArray(v) ? v : {});
|
|
216
|
+
const names = (v) => (Array.isArray(v) ? v.filter((x) => typeof x === 'string').slice(0, 50) : []);
|
|
217
|
+
const strMap = (v) => Object.fromEntries(Object.entries(obj(v)).slice(0, 50).filter(([, x]) => typeof x === 'string'));
|
|
218
|
+
const empty = (error) => ({ accessTokenClaims: {}, idTokenClaims: {}, appMetadata: {}, sessionData: {}, denied: false, denyReason: null, lockReason: null, pauseReason: null, suppressedAccessClaims: [], suppressedIdClaims: [], userEdits: {}, signUpPrefill: {}, signUpModify: {}, httpRequests: [], connectorCalls: [], logs: [], error });
|
|
219
|
+
/** The requests the sandbox recorded, checked again here: the sandbox's output is untrusted data. */
|
|
220
|
+
function httpOf(raw) {
|
|
221
|
+
if (!Array.isArray(raw))
|
|
222
|
+
return [];
|
|
223
|
+
const out = [];
|
|
224
|
+
for (const item of raw.slice(0, ACTION_HTTP_LIMITS.perAction)) {
|
|
225
|
+
const r = obj(item);
|
|
226
|
+
if (r.method !== 'GET' && r.method !== 'POST')
|
|
227
|
+
continue;
|
|
228
|
+
if (typeof r.url !== 'string' || r.url.length > ACTION_HTTP_LIMITS.urlMax)
|
|
229
|
+
continue;
|
|
230
|
+
let u;
|
|
231
|
+
try {
|
|
232
|
+
u = new URL(r.url);
|
|
233
|
+
}
|
|
234
|
+
catch {
|
|
235
|
+
continue;
|
|
236
|
+
}
|
|
237
|
+
if (u.protocol !== 'https:' || u.username || u.password)
|
|
238
|
+
continue;
|
|
239
|
+
const headers = Object.fromEntries(Object.entries(obj(r.headers)).slice(0, ACTION_HTTP_LIMITS.headersMax).filter(([, v]) => typeof v === 'string'));
|
|
240
|
+
out.push({ method: r.method, url: u.toString(), headers, body: typeof r.body === 'string' ? r.body : null, saveResponseAs: typeof r.saveResponseAs === 'string' ? r.saveResponseAs : null });
|
|
241
|
+
}
|
|
242
|
+
return out;
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Run one Action's code. Never throws: a syntax error, a thrown exception, a timeout or a promise that never settles comes back
|
|
246
|
+
* as `error` (the caller fails closed or open by trigger, as the real flow does). Returns null when the code is not in the
|
|
247
|
+
* runtime's form or vm is not available, so the caller can read it declaratively instead.
|
|
248
|
+
*/
|
|
249
|
+
function runActionCode(event, code) {
|
|
250
|
+
const vm = vmModule();
|
|
251
|
+
if (!vm || !(0, exports.isRuntimeForm)(code))
|
|
252
|
+
return null;
|
|
253
|
+
const literal = JSON.stringify(JSON.stringify(event));
|
|
254
|
+
const head = BOOTSTRAP.replace("'use strict';", () => `'use strict';\nglobalThis.__atlas_event_raw = JSON.parse(${literal});`);
|
|
255
|
+
const src = head +
|
|
256
|
+
'\n;(async function () {\n' +
|
|
257
|
+
code +
|
|
258
|
+
'\n})().then(' +
|
|
259
|
+
'function () { globalThis.__atlas_out = JSON.stringify(__atlas_result); },' +
|
|
260
|
+
'function (e) {' +
|
|
261
|
+
' __atlas_result.error = (e && e.message) ? String(e.message).slice(0,512) : String(e).slice(0,512);' +
|
|
262
|
+
' globalThis.__atlas_out = JSON.stringify(__atlas_result);' +
|
|
263
|
+
'})';
|
|
264
|
+
let json;
|
|
265
|
+
try {
|
|
266
|
+
const context = vm.createContext(Object.create(null), { codeGeneration: { strings: false, wasm: false }, microtaskMode: 'afterEvaluate' });
|
|
267
|
+
new vm.Script(src).runInContext(context, { timeout: exports.ACTION_TIMEOUT_MS });
|
|
268
|
+
json = vm.runInContext('globalThis.__atlas_out', context, { timeout: exports.ACTION_TIMEOUT_MS });
|
|
269
|
+
}
|
|
270
|
+
catch (err) {
|
|
271
|
+
return empty(String(err?.message ?? err).slice(0, 512));
|
|
272
|
+
}
|
|
273
|
+
// An awaited promise that never settles leaves nothing behind: the real service's watchdog reports the same.
|
|
274
|
+
if (typeof json !== 'string')
|
|
275
|
+
return empty('Action timed out.');
|
|
276
|
+
if (json.length > MAX_OUT)
|
|
277
|
+
return empty('Action output is too large.');
|
|
278
|
+
let p;
|
|
279
|
+
try {
|
|
280
|
+
p = JSON.parse(json);
|
|
281
|
+
}
|
|
282
|
+
catch {
|
|
283
|
+
return empty('Action returned an unreadable result.');
|
|
284
|
+
}
|
|
285
|
+
const edits = obj(p.userEdits);
|
|
286
|
+
const userEdits = {};
|
|
287
|
+
const banned = obj(edits.banned);
|
|
288
|
+
if (typeof banned.value === 'boolean')
|
|
289
|
+
userEdits.banned = { value: banned.value, reason: typeof banned.reason === 'string' ? banned.reason : null };
|
|
290
|
+
if (typeof edits.emailVerified === 'boolean')
|
|
291
|
+
userEdits.emailVerified = edits.emailVerified;
|
|
292
|
+
for (const k of ['firstName', 'lastName', 'imageUrl'])
|
|
293
|
+
if (edits[k] === null || typeof edits[k] === 'string')
|
|
294
|
+
userEdits[k] = edits[k];
|
|
295
|
+
const calls = (Array.isArray(p.connectorCalls) ? p.connectorCalls : []).slice(0, ACTION_CONNECTOR_LIMITS.perAction).map(obj).filter((c) => typeof c.name === 'string' && /^[a-z0-9][a-z0-9_-]{0,62}$/.test(c.name) && typeof c.operation === 'string' && /^[a-z_]{1,64}$/.test(c.operation));
|
|
296
|
+
return {
|
|
297
|
+
accessTokenClaims: obj(p.accessTokenClaims),
|
|
298
|
+
idTokenClaims: obj(p.idTokenClaims),
|
|
299
|
+
appMetadata: obj(p.appMetadata),
|
|
300
|
+
sessionData: obj(p.sessionData),
|
|
301
|
+
denied: p.denied === true,
|
|
302
|
+
denyReason: typeof p.denyReason === 'string' ? p.denyReason : null,
|
|
303
|
+
lockReason: typeof p.lockReason === 'string' ? p.lockReason : null,
|
|
304
|
+
pauseReason: typeof p.pauseReason === 'string' ? p.pauseReason : null,
|
|
305
|
+
suppressedAccessClaims: names(p.suppressedAccessClaims),
|
|
306
|
+
suppressedIdClaims: names(p.suppressedIdClaims),
|
|
307
|
+
userEdits,
|
|
308
|
+
signUpPrefill: strMap(p.signUpPrefill),
|
|
309
|
+
signUpModify: strMap(p.signUpModify),
|
|
310
|
+
httpRequests: httpOf(p.http),
|
|
311
|
+
connectorCalls: calls,
|
|
312
|
+
logs: Array.isArray(p.logs) ? p.logs.map(String) : [],
|
|
313
|
+
error: typeof p.error === 'string' ? p.error : null,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
/** One row per Action run (what the emulator saw: outcome, deny reason, logs, the requests `api.http` queued), read at `/__emulator/actions/runs`. */
|
|
317
|
+
exports.actionRuns = (0, support_1.engineState)((e) => new store_1.Table('action_runs', e.clock.now, 'arun'));
|
|
318
|
+
//# sourceMappingURL=emu4-actions-sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emu4-actions-sandbox.js","sourceRoot":"","sources":["../../src/handlers/emu4-actions-sandbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { ActionDef } from './emu4-actions-def';
|
|
2
|
+
/** A JSON Schema as a TypeScript type expression (the subset action schemas use). Unknown shapes become `unknown`. */
|
|
3
|
+
export declare function schemaToTs(schema: unknown, depth?: number): string;
|
|
4
|
+
/** The declaration source for a set of actions (any providers). */
|
|
5
|
+
export declare function actionTypesSource(actions: ActionDef[]): string;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.schemaToTs = schemaToTs;
|
|
4
|
+
exports.actionTypesSource = actionTypesSource;
|
|
5
|
+
/**
|
|
6
|
+
* TypeScript declarations for a connection action catalog: one entry per provider and action with its input and output
|
|
7
|
+
* types, so `atlas.connections.runAction(id, 'list_issues', input)` can be typed end to end. Generated from the same JSON
|
|
8
|
+
* Schemas Atlas validates with, so the types and the checks cannot disagree.
|
|
9
|
+
*/
|
|
10
|
+
const IDENT = /^[A-Za-z_$][A-Za-z0-9_$]*$/;
|
|
11
|
+
const key = (k) => (IDENT.test(k) ? k : JSON.stringify(k));
|
|
12
|
+
const pad = (n) => ' '.repeat(n);
|
|
13
|
+
/** A JSON Schema as a TypeScript type expression (the subset action schemas use). Unknown shapes become `unknown`. */
|
|
14
|
+
function schemaToTs(schema, depth = 0) {
|
|
15
|
+
if (typeof schema !== 'object' || schema === null)
|
|
16
|
+
return 'unknown';
|
|
17
|
+
const s = schema;
|
|
18
|
+
if (Array.isArray(s.enum) && s.enum.length)
|
|
19
|
+
return s.enum.map((v) => JSON.stringify(v)).join(' | ');
|
|
20
|
+
const types = Array.isArray(s.type) ? s.type : s.type === undefined ? [] : [String(s.type)];
|
|
21
|
+
if (types.length === 0)
|
|
22
|
+
return 'unknown';
|
|
23
|
+
return types
|
|
24
|
+
.map((t) => {
|
|
25
|
+
switch (t) {
|
|
26
|
+
case 'string':
|
|
27
|
+
return 'string';
|
|
28
|
+
case 'integer':
|
|
29
|
+
case 'number':
|
|
30
|
+
return 'number';
|
|
31
|
+
case 'boolean':
|
|
32
|
+
return 'boolean';
|
|
33
|
+
case 'null':
|
|
34
|
+
return 'null';
|
|
35
|
+
case 'array':
|
|
36
|
+
return `Array<${schemaToTs(s.items, depth)}>`;
|
|
37
|
+
case 'object': {
|
|
38
|
+
const props = (s.properties ?? {});
|
|
39
|
+
const required = new Set((s.required ?? []));
|
|
40
|
+
const names = Object.keys(props);
|
|
41
|
+
if (names.length === 0)
|
|
42
|
+
return s.additionalProperties === false ? 'Record<string, never>' : 'Record<string, unknown>';
|
|
43
|
+
const lines = names.map((n) => {
|
|
44
|
+
const doc = typeof props[n]?.description === 'string' ? `${pad(depth + 1)}/** ${String(props[n].description).replace(/\*\//g, '* /')} */\n` : '';
|
|
45
|
+
return `${doc}${pad(depth + 1)}${key(n)}${required.has(n) ? '' : '?'}: ${schemaToTs(props[n], depth + 1)};`;
|
|
46
|
+
});
|
|
47
|
+
const open = s.additionalProperties === false ? '' : `\n${pad(depth + 1)}[key: string]: unknown;`;
|
|
48
|
+
return `{\n${lines.join('\n')}${open}\n${pad(depth)}}`;
|
|
49
|
+
}
|
|
50
|
+
default:
|
|
51
|
+
return 'unknown';
|
|
52
|
+
}
|
|
53
|
+
})
|
|
54
|
+
.join(' | ');
|
|
55
|
+
}
|
|
56
|
+
/** The declaration source for a set of actions (any providers). */
|
|
57
|
+
function actionTypesSource(actions) {
|
|
58
|
+
const byProvider = new Map();
|
|
59
|
+
for (const a of actions)
|
|
60
|
+
byProvider.set(a.provider, [...(byProvider.get(a.provider) ?? []), a]);
|
|
61
|
+
const body = [...byProvider.entries()]
|
|
62
|
+
.sort(([a], [b]) => (a < b ? -1 : 1))
|
|
63
|
+
.map(([provider, list]) => {
|
|
64
|
+
const ops = list
|
|
65
|
+
.sort((a, b) => (a.name < b.name ? -1 : 1))
|
|
66
|
+
.map((a) => `${pad(2)}/** ${a.description.replace(/\*\//g, '* /')} */\n${pad(2)}${key(a.name)}: {\n${pad(3)}input: ${schemaToTs(a.input, 3)};\n${pad(3)}output: ${a.output ? schemaToTs(a.output, 3) : 'unknown'};\n${pad(2)}};`)
|
|
67
|
+
.join('\n');
|
|
68
|
+
return `${pad(1)}${key(provider)}: {\n${ops}\n${pad(1)}};`;
|
|
69
|
+
})
|
|
70
|
+
.join('\n');
|
|
71
|
+
return `// Generated by Atlas from your connection action catalog. Do not edit.\nexport interface ConnectionActionCatalog {\n${body}\n}\n\nexport type ConnectionActionProvider = keyof ConnectionActionCatalog;\nexport type ConnectionActionInput<P extends ConnectionActionProvider, A extends keyof ConnectionActionCatalog[P]> = ConnectionActionCatalog[P][A] extends { input: infer I } ? I : never;\nexport type ConnectionActionOutput<P extends ConnectionActionProvider, A extends keyof ConnectionActionCatalog[P]> = ConnectionActionCatalog[P][A] extends { output: infer O } ? O : never;\n`;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=emu4-actions-typegen.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"emu4-actions-typegen.js","sourceRoot":"","sources":["../../src/handlers/emu4-actions-typegen.ts"],"names":[],"mappings":"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"}
|