@teleporthq/teleport-plugin-next-workflows 0.44.7 → 0.44.8
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/__tests__/credential-result-reply.test.ts +509 -0
- package/dist/cjs/api-route-generator.d.ts.map +1 -1
- package/dist/cjs/api-route-generator.js +5 -2
- package/dist/cjs/api-route-generator.js.map +1 -1
- package/dist/cjs/credential-results.d.ts +18 -0
- package/dist/cjs/credential-results.d.ts.map +1 -0
- package/dist/cjs/credential-results.js +72 -0
- package/dist/cjs/credential-results.js.map +1 -0
- package/dist/cjs/executor-generator.d.ts.map +1 -1
- package/dist/cjs/executor-generator.js +8 -1
- package/dist/cjs/executor-generator.js.map +1 -1
- package/dist/cjs/nodes/account/account-hash-password.d.ts.map +1 -1
- package/dist/cjs/nodes/account/account-hash-password.js +1 -0
- package/dist/cjs/nodes/account/account-hash-password.js.map +1 -1
- package/dist/cjs/nodes/types.d.ts +6 -0
- package/dist/cjs/nodes/types.d.ts.map +1 -1
- package/dist/cjs/server-runtime-code.d.ts +8 -0
- package/dist/cjs/server-runtime-code.d.ts.map +1 -1
- package/dist/cjs/server-runtime-code.js +106 -0
- package/dist/cjs/server-runtime-code.js.map +1 -1
- package/dist/cjs/tsconfig.tsbuildinfo +1 -1
- package/dist/esm/api-route-generator.d.ts.map +1 -1
- package/dist/esm/api-route-generator.js +5 -2
- package/dist/esm/api-route-generator.js.map +1 -1
- package/dist/esm/credential-results.d.ts +18 -0
- package/dist/esm/credential-results.d.ts.map +1 -0
- package/dist/esm/credential-results.js +68 -0
- package/dist/esm/credential-results.js.map +1 -0
- package/dist/esm/executor-generator.d.ts.map +1 -1
- package/dist/esm/executor-generator.js +8 -1
- package/dist/esm/executor-generator.js.map +1 -1
- package/dist/esm/nodes/account/account-hash-password.d.ts.map +1 -1
- package/dist/esm/nodes/account/account-hash-password.js +1 -0
- package/dist/esm/nodes/account/account-hash-password.js.map +1 -1
- package/dist/esm/nodes/types.d.ts +6 -0
- package/dist/esm/nodes/types.d.ts.map +1 -1
- package/dist/esm/server-runtime-code.d.ts +8 -0
- package/dist/esm/server-runtime-code.d.ts.map +1 -1
- package/dist/esm/server-runtime-code.js +106 -0
- package/dist/esm/server-runtime-code.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
- package/src/api-route-generator.ts +5 -2
- package/src/credential-results.ts +71 -0
- package/src/executor-generator.ts +8 -1
- package/src/nodes/account/account-hash-password.ts +1 -0
- package/src/nodes/types.ts +6 -0
- package/src/server-runtime-code.ts +106 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.generateCredentialResultsCode = exports.CREDENTIAL_RESULT_NODE_TYPES = void 0;
|
|
4
|
+
const nodes_1 = require("./nodes");
|
|
5
|
+
/**
|
|
6
|
+
* The node types whose result is a credential, read off the node registry
|
|
7
|
+
* (`resultIsCredential`): today the password-hashing node. Its result stays on
|
|
8
|
+
* the server. A server segment replies it to the browser only sealed —
|
|
9
|
+
* encrypted with a key derived from the app secret, signed like every other
|
|
10
|
+
* result — and a later server segment opens it again, so a workflow that
|
|
11
|
+
* hashes in one segment and writes in another still works (see the server
|
|
12
|
+
* runtime: `sealResult`, `openSealedResults`).
|
|
13
|
+
*/
|
|
14
|
+
exports.CREDENTIAL_RESULT_NODE_TYPES = Object.keys(nodes_1.nodeRegistry).filter((nodeType) => nodes_1.nodeRegistry[nodeType].resultIsCredential === true);
|
|
15
|
+
/**
|
|
16
|
+
* `credentialResultNodeIds(segmentConfig)`: the nodes of a segment whose
|
|
17
|
+
* result is a credential — every node of a credential type, and every map
|
|
18
|
+
* loop whose results are such a node's results (the loop's last body step, as
|
|
19
|
+
* the route runs it; a loop of loops follows its inner loop).
|
|
20
|
+
*/
|
|
21
|
+
const generateCredentialResultsCode = () => `
|
|
22
|
+
var __CREDENTIAL_RESULT_NODE_TYPES = ${JSON.stringify(exports.CREDENTIAL_RESULT_NODE_TYPES)};
|
|
23
|
+
|
|
24
|
+
function lastLoopBodyNodeId(loopId, sortedNodes, edges) {
|
|
25
|
+
var start = edges.find(function(e) { return e.source === loopId && e.sourceHandle === 'loop'; });
|
|
26
|
+
if (!start) return null;
|
|
27
|
+
var body = {};
|
|
28
|
+
var queue = [start.target];
|
|
29
|
+
while (queue.length > 0) {
|
|
30
|
+
var current = queue.shift();
|
|
31
|
+
if (body[current] || current === loopId) continue;
|
|
32
|
+
body[current] = true;
|
|
33
|
+
edges.forEach(function(e) {
|
|
34
|
+
if (e.source === current && (e.sourceHandle === 'loop-body-out' || !e.sourceHandle) && e.target !== loopId) {
|
|
35
|
+
queue.push(e.target);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
var last = null;
|
|
40
|
+
sortedNodes.forEach(function(n) { if (body[n.id]) last = n.id; });
|
|
41
|
+
return last;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function credentialResultNodeIds(segmentConfig) {
|
|
45
|
+
var nodes = (segmentConfig && segmentConfig.nodes) || [];
|
|
46
|
+
var edges = (segmentConfig && segmentConfig.edges) || [];
|
|
47
|
+
var ids = {};
|
|
48
|
+
nodes.forEach(function(n) {
|
|
49
|
+
if (__CREDENTIAL_RESULT_NODE_TYPES.indexOf(n.type) !== -1) ids[n.id] = true;
|
|
50
|
+
});
|
|
51
|
+
var sortedNodes = nodes.slice().sort(function(a, b) { return (a.stepNumber || 0) - (b.stepNumber || 0); });
|
|
52
|
+
var mapLoops = nodes.filter(function(n) {
|
|
53
|
+
var loopType = n.config && n.config.loopType;
|
|
54
|
+
return n.type === 'general-loop' && !!loopType && loopType !== 'forEach';
|
|
55
|
+
});
|
|
56
|
+
var grew = true;
|
|
57
|
+
while (grew) {
|
|
58
|
+
grew = false;
|
|
59
|
+
mapLoops.forEach(function(loop) {
|
|
60
|
+
if (ids[loop.id]) return;
|
|
61
|
+
var last = lastLoopBodyNodeId(loop.id, sortedNodes, edges);
|
|
62
|
+
if (last && ids[last]) {
|
|
63
|
+
ids[loop.id] = true;
|
|
64
|
+
grew = true;
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
return ids;
|
|
69
|
+
}
|
|
70
|
+
`;
|
|
71
|
+
exports.generateCredentialResultsCode = generateCredentialResultsCode;
|
|
72
|
+
//# sourceMappingURL=credential-results.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credential-results.js","sourceRoot":"","sources":["../../src/credential-results.ts"],"names":[],"mappings":";;;AAAA,mCAAsC;AAEtC;;;;;;;;GAQG;AACU,QAAA,4BAA4B,GAAa,MAAM,CAAC,IAAI,CAAC,oBAAY,CAAC,CAAC,MAAM,CACpF,CAAC,QAAQ,EAAE,EAAE,CAAC,oBAAY,CAAC,QAAQ,CAAC,CAAC,kBAAkB,KAAK,IAAI,CACjE,CAAA;AAED;;;;;GAKG;AACI,MAAM,6BAA6B,GAAG,GAAW,EAAE,CAAC;uCACpB,IAAI,CAAC,SAAS,CAAC,oCAA4B,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgDlF,CAAA;AAjDY,QAAA,6BAA6B,iCAiDzC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor-generator.d.ts","sourceRoot":"","sources":["../../src/executor-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAGlB,MAAM,gBAAgB,CAAA;
|
|
1
|
+
{"version":3,"file":"executor-generator.d.ts","sourceRoot":"","sources":["../../src/executor-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAGlB,MAAM,gBAAgB,CAAA;AAKvB,MAAM,WAAW,yBAAyB;IACxC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,iBAAiB,CAAA;CACjC;AAID,eAAO,MAAM,8BAA8B,aAAa,yBAAyB,KAAQ,MAw/CxF,CAAA;AAED,eAAO,MAAM,yBAAyB,QAAO,MA+nB5C,CAAA"}
|
|
@@ -4,6 +4,7 @@ exports.generateClientRuntimeCode = exports.generateSharedRuntimeUtilsCode = voi
|
|
|
4
4
|
const email_locale_1 = require("./email-locale");
|
|
5
5
|
const signed_in_destination_code_1 = require("./auth-return/signed-in-destination-code");
|
|
6
6
|
const credential_columns_code_1 = require("./credential-columns-code");
|
|
7
|
+
const credential_results_1 = require("./credential-results");
|
|
7
8
|
const NO_EMAIL_LOCALES = { locales: [], defaultLocale: '' };
|
|
8
9
|
const generateSharedRuntimeUtilsCode = (options = {}) => {
|
|
9
10
|
return `/**
|
|
@@ -1405,7 +1406,12 @@ var SEGMENT_REPLY_PRIVATE_KEYS = {
|
|
|
1405
1406
|
//
|
|
1406
1407
|
// A data node's rows are replied without the auth users table's credentials
|
|
1407
1408
|
// (see credential-columns-code.ts).
|
|
1409
|
+
//
|
|
1410
|
+
// A node whose result is a credential (a password hash) is left out here too,
|
|
1411
|
+
// whatever its config says: the server runtime replies it sealed, readable by
|
|
1412
|
+
// a later server segment only (see credential-results.ts).
|
|
1408
1413
|
${(0, credential_columns_code_1.generateCredentialColumnsCode)()}
|
|
1414
|
+
${(0, credential_results_1.generateCredentialResultsCode)()}
|
|
1409
1415
|
// The nodes whose result the client branches on: never kept on the server.
|
|
1410
1416
|
function isBranchingNodeType(type) {
|
|
1411
1417
|
return type === 'general-if-statement' || type === 'general-switch';
|
|
@@ -1414,7 +1420,7 @@ function isBranchingNodeType(type) {
|
|
|
1414
1420
|
function segmentReply(segmentConfig, context, snapshot) {
|
|
1415
1421
|
var reply = {};
|
|
1416
1422
|
var own = {};
|
|
1417
|
-
var kept =
|
|
1423
|
+
var kept = credentialResultNodeIds(segmentConfig);
|
|
1418
1424
|
var nodes = (segmentConfig && segmentConfig.nodes) || [];
|
|
1419
1425
|
for (var ni = 0; ni < nodes.length; ni++) {
|
|
1420
1426
|
own[nodes[ni].id] = nodes[ni];
|
|
@@ -1501,6 +1507,7 @@ module.exports = {
|
|
|
1501
1507
|
snapshotIncomingContext,
|
|
1502
1508
|
segmentReply,
|
|
1503
1509
|
withoutCredentialColumns,
|
|
1510
|
+
credentialResultNodeIds,
|
|
1504
1511
|
evaluateCondition,
|
|
1505
1512
|
evaluateSingleComparison,
|
|
1506
1513
|
normalizeComparisonOperator,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"executor-generator.js","sourceRoot":"","sources":["../../src/executor-generator.ts"],"names":[],"mappings":";;;AAAA,iDAIuB;AACvB,yFAA0F;AAC1F,uEAAyE;
|
|
1
|
+
{"version":3,"file":"executor-generator.js","sourceRoot":"","sources":["../../src/executor-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-hash-password.d.ts","sourceRoot":"","sources":["../../../../src/nodes/account/account-hash-password.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAmB,MAAM,UAAU,CAAA;AA8ChE,eAAO,MAAM,mBAAmB,EAAE,
|
|
1
|
+
{"version":3,"file":"account-hash-password.d.ts","sourceRoot":"","sources":["../../../../src/nodes/account/account-hash-password.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAmB,MAAM,UAAU,CAAA;AA8ChE,eAAO,MAAM,mBAAmB,EAAE,oBAUjC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"account-hash-password.js","sourceRoot":"","sources":["../../../../src/nodes/account/account-hash-password.ts"],"names":[],"mappings":";;;AAAA,oCAAgE;AAEhE,KAAK,UAAU,qBAAqB,CAAC,MAAW,EAAE,OAAgC;IAChF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;IAChC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAEnF,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,EAAE,EAAE;QAChC,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAA;KACxC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAA;IAEpC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;KAC5C;IAED,IAAI,WAAW,CAAC,MAAM,GAAG,IAAI,EAAE;QAC7B,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;KACnD;IAED,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,GAAG,EAAE,EAAE;QACtE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;KACnE;IAED,yEAAyE;IACzE,mEAAmE;IACnE,2EAA2E;IAC3E,4EAA4E;IAC5E,4EAA4E;IAC5E,uEAAuE;IACvE,oEAAoE;IACpE,MAAM,aAAa,GACjB,OAAO,uBAAuB,KAAK,WAAW,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,OAAO,CAAA;IACpF,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;IACxC,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAA;IAEtC,MAAM,MAAM,GAAI,UAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAA;IAChE,MAAM,GAAG,GAAG,MAAM;SACf,UAAU,CAAC,QAAQ,CAAC;SACpB,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC;SAC5B,MAAM,CAAC,QAAQ,CAAC,CAAA;IACnB,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;IAE7C,OAAO,EAAE,IAAI,EAAE,CAAA;AACjB,CAAC;AAEY,QAAA,mBAAmB,GAAyB;IACvD,QAAQ,EAAE,uBAAuB;IACjC,YAAY,EAAE,QAAQ;IACtB,YAAY,EAAE;QACZ,QAAQ,EAAE,QAAQ;KACnB;IACD,eAAe;QACb,OAAO,IAAA,uBAAe,EAAC,qBAAqB,CAAC,CAAA;IAC/C,CAAC;CACF,CAAA"}
|
|
1
|
+
{"version":3,"file":"account-hash-password.js","sourceRoot":"","sources":["../../../../src/nodes/account/account-hash-password.ts"],"names":[],"mappings":";;;AAAA,oCAAgE;AAEhE,KAAK,UAAU,qBAAqB,CAAC,MAAW,EAAE,OAAgC;IAChF,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;IAChC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAEnF,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,EAAE,EAAE;QAChC,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAA;KACxC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAA;IAEpC,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE;QAC5B,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAA;KAC5C;IAED,IAAI,WAAW,CAAC,MAAM,GAAG,IAAI,EAAE;QAC7B,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;KACnD;IAED,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,IAAI,UAAU,GAAG,EAAE,EAAE;QACtE,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAA;KACnE;IAED,yEAAyE;IACzE,mEAAmE;IACnE,2EAA2E;IAC3E,4EAA4E;IAC5E,4EAA4E;IAC5E,uEAAuE;IACvE,oEAAoE;IACpE,MAAM,aAAa,GACjB,OAAO,uBAAuB,KAAK,WAAW,CAAC,CAAC,CAAC,uBAAuB,CAAC,CAAC,CAAC,OAAO,CAAA;IACpF,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC,CAAA;IACxC,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAA;IAEtC,MAAM,MAAM,GAAI,UAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAA;IAChE,MAAM,GAAG,GAAG,MAAM;SACf,UAAU,CAAC,QAAQ,CAAC;SACpB,MAAM,CAAC,WAAW,GAAG,MAAM,CAAC;SAC5B,MAAM,CAAC,QAAQ,CAAC,CAAA;IACnB,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC,CAAA;IAE7C,OAAO,EAAE,IAAI,EAAE,CAAA;AACjB,CAAC;AAEY,QAAA,mBAAmB,GAAyB;IACvD,QAAQ,EAAE,uBAAuB;IACjC,YAAY,EAAE,QAAQ;IACtB,kBAAkB,EAAE,IAAI;IACxB,YAAY,EAAE;QACZ,QAAQ,EAAE,QAAQ;KACnB;IACD,eAAe;QACb,OAAO,IAAA,uBAAe,EAAC,qBAAqB,CAAC,CAAA;IAC/C,CAAC;CACF,CAAA"}
|
|
@@ -5,6 +5,12 @@ export interface NodeHandlerGenerator {
|
|
|
5
5
|
nodeType: string;
|
|
6
6
|
executionEnv: 'client' | 'server' | 'universal';
|
|
7
7
|
isTerminal?: boolean;
|
|
8
|
+
/**
|
|
9
|
+
* The node's result is a credential (a password hash). A server segment
|
|
10
|
+
* never replies it as it is: the browser receives it sealed, and only the
|
|
11
|
+
* app's own later server segments can open it (see credential-results.ts).
|
|
12
|
+
*/
|
|
13
|
+
resultIsCredential?: boolean;
|
|
8
14
|
dependencies?: Record<string, string>;
|
|
9
15
|
generateHandler(): string;
|
|
10
16
|
generateServerHandler?(): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/nodes/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAE/F,wBAAgB,eAAe,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,CAErD;AAkCD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAwEhF;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAA;IAC/C,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,eAAe,IAAI,MAAM,CAAA;IACzB,qBAAqB,CAAC,IAAI,MAAM,CAAA;CACjC;AAED,MAAM,WAAW,2BAA4B,SAAQ,oBAAoB;IACvE,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/nodes/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAA;AAE/F,wBAAgB,eAAe,CAAC,EAAE,EAAE,SAAS,GAAG,MAAM,CAErD;AAkCD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAwEhF;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAA;IAC/C,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,eAAe,IAAI,MAAM,CAAA;IACzB,qBAAqB,CAAC,IAAI,MAAM,CAAA;CACjC;AAED,MAAM,WAAW,2BAA4B,SAAQ,oBAAoB;IACvE,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB"}
|
|
@@ -27,6 +27,14 @@
|
|
|
27
27
|
* that needs a trustworthy figure (a price, an owner) reads it from the
|
|
28
28
|
* database itself.
|
|
29
29
|
*
|
|
30
|
+
* A result that is a credential (a password hash, see credential-results.ts)
|
|
31
|
+
* makes the same trip SEALED: `segmentReply` replies it encrypted with a key
|
|
32
|
+
* derived from NEXTAUTH_SECRET (AES-256-GCM) and signs the sealed form, and
|
|
33
|
+
* `claimSegmentContext` opens every sealed value a request hands it (a
|
|
34
|
+
* relayed result once its signature holds). The browser relays it without
|
|
35
|
+
* ever reading it, and a later segment's reply hands back the sealed form,
|
|
36
|
+
* never the opened one.
|
|
37
|
+
*
|
|
30
38
|
* The facts about the graph each route needs are baked into its
|
|
31
39
|
* SEGMENT_CONFIG at generation time (see segment-trust.ts).
|
|
32
40
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-runtime-code.d.ts","sourceRoot":"","sources":["../../src/server-runtime-code.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"server-runtime-code.d.ts","sourceRoot":"","sources":["../../src/server-runtime-code.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,eAAO,MAAM,yBAAyB,QAAO,MA2W5C,CAAA"}
|
|
@@ -30,6 +30,14 @@ exports.generateServerRuntimeCode = void 0;
|
|
|
30
30
|
* that needs a trustworthy figure (a price, an owner) reads it from the
|
|
31
31
|
* database itself.
|
|
32
32
|
*
|
|
33
|
+
* A result that is a credential (a password hash, see credential-results.ts)
|
|
34
|
+
* makes the same trip SEALED: `segmentReply` replies it encrypted with a key
|
|
35
|
+
* derived from NEXTAUTH_SECRET (AES-256-GCM) and signs the sealed form, and
|
|
36
|
+
* `claimSegmentContext` opens every sealed value a request hands it (a
|
|
37
|
+
* relayed result once its signature holds). The browser relays it without
|
|
38
|
+
* ever reading it, and a later segment's reply hands back the sealed form,
|
|
39
|
+
* never the opened one.
|
|
40
|
+
*
|
|
33
41
|
* The facts about the graph each route needs are baked into its
|
|
34
42
|
* SEGMENT_CONFIG at generation time (see segment-trust.ts).
|
|
35
43
|
*/
|
|
@@ -54,6 +62,59 @@ function mac(text) {
|
|
|
54
62
|
return crypto.createHmac('sha256', stepKey()).update(text).digest('hex');
|
|
55
63
|
}
|
|
56
64
|
|
|
65
|
+
var __sealKeyCache = { secret: null, key: null };
|
|
66
|
+
|
|
67
|
+
function sealKey() {
|
|
68
|
+
var secret = process.env.NEXTAUTH_SECRET || '';
|
|
69
|
+
if (__sealKeyCache.secret !== secret) {
|
|
70
|
+
__sealKeyCache = {
|
|
71
|
+
secret: secret,
|
|
72
|
+
key: crypto.createHmac('sha256', secret).update('teleport-workflow-seal:v1').digest()
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
return __sealKeyCache.key;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
var SEAL_IV_BYTES = 12;
|
|
79
|
+
var SEAL_TAG_BYTES = 16;
|
|
80
|
+
|
|
81
|
+
var SEAL_AAD = Buffer.from('teleport-workflow-sealed-result:v1', 'utf8');
|
|
82
|
+
|
|
83
|
+
// The sealed form of a credential result; undefined (the result is then not
|
|
84
|
+
// replied at all) without an app secret, whose key anyone could derive.
|
|
85
|
+
function sealResult(value) {
|
|
86
|
+
if (!process.env.NEXTAUTH_SECRET) return undefined;
|
|
87
|
+
var serialized;
|
|
88
|
+
try { serialized = JSON.stringify(value); } catch (e) { return undefined; }
|
|
89
|
+
if (serialized === undefined) return undefined;
|
|
90
|
+
var iv = crypto.randomBytes(SEAL_IV_BYTES);
|
|
91
|
+
var cipher = crypto.createCipheriv('aes-256-gcm', sealKey(), iv);
|
|
92
|
+
cipher.setAAD(SEAL_AAD);
|
|
93
|
+
var data = Buffer.concat([cipher.update(serialized, 'utf8'), cipher.final()]);
|
|
94
|
+
return { __sealed: Buffer.concat([iv, cipher.getAuthTag(), data]).toString('base64') };
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
function isSealedResult(value) {
|
|
98
|
+
return !!value && typeof value === 'object' && !Array.isArray(value) &&
|
|
99
|
+
typeof value.__sealed === 'string' && Object.keys(value).length === 1;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// { value } when the sealed form opens under this app's key, else null.
|
|
103
|
+
function openSealedResult(sealed) {
|
|
104
|
+
if (!process.env.NEXTAUTH_SECRET) return null;
|
|
105
|
+
try {
|
|
106
|
+
var raw = Buffer.from(sealed.__sealed, 'base64');
|
|
107
|
+
if (raw.length <= SEAL_IV_BYTES + SEAL_TAG_BYTES) return null;
|
|
108
|
+
var decipher = crypto.createDecipheriv('aes-256-gcm', sealKey(), raw.subarray(0, SEAL_IV_BYTES));
|
|
109
|
+
decipher.setAAD(SEAL_AAD);
|
|
110
|
+
decipher.setAuthTag(raw.subarray(SEAL_IV_BYTES, SEAL_IV_BYTES + SEAL_TAG_BYTES));
|
|
111
|
+
var data = Buffer.concat([decipher.update(raw.subarray(SEAL_IV_BYTES + SEAL_TAG_BYTES)), decipher.final()]);
|
|
112
|
+
return { value: JSON.parse(data.toString('utf8')) };
|
|
113
|
+
} catch (e) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
57
118
|
// Without an app secret every key here would derive from '' — a value anyone
|
|
58
119
|
// can compute — so nothing verifies: relayed server results are dropped and no
|
|
59
120
|
// request passes as an internal call. (The generator gives every app with
|
|
@@ -209,10 +270,48 @@ function resetPreviousResult(segmentConfig, context) {
|
|
|
209
270
|
// merge will.
|
|
210
271
|
var __incomingOrders = new WeakMap();
|
|
211
272
|
|
|
273
|
+
// The sealed results this segment opened, so its reply hands the caller back
|
|
274
|
+
// the sealed form it relayed (see resealRelayedResults).
|
|
275
|
+
var __openedResults = new WeakMap();
|
|
276
|
+
|
|
277
|
+
// Opens every sealed value the request hands this segment, so its nodes read
|
|
278
|
+
// the credential itself: a relayed server result (whose signature
|
|
279
|
+
// dropUnsignedResults checked first), or a value the browser holds from one
|
|
280
|
+
// (a custom node's output, the previous result). Only this app's server
|
|
281
|
+
// seals, so what opens is what it sealed.
|
|
282
|
+
function openSealedResults(context) {
|
|
283
|
+
var opened = [];
|
|
284
|
+
Object.keys(context).forEach(function(key) {
|
|
285
|
+
if (isControlKey(key) && key !== '__previousNodeResult') return;
|
|
286
|
+
if (!isSealedResult(context[key])) return;
|
|
287
|
+
var result = openSealedResult(context[key]);
|
|
288
|
+
if (!result) return;
|
|
289
|
+
opened.push({ sealed: context[key], value: result.value });
|
|
290
|
+
context[key] = result.value;
|
|
291
|
+
});
|
|
292
|
+
__openedResults.set(context, opened);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Every reply entry that is an opened value (the value itself, or the previous
|
|
296
|
+
// result taken from it) goes back sealed.
|
|
297
|
+
function resealRelayedResults(context, reply) {
|
|
298
|
+
var opened = __openedResults.get(context) || [];
|
|
299
|
+
if (opened.length === 0) return;
|
|
300
|
+
Object.keys(reply).forEach(function(key) {
|
|
301
|
+
for (var i = 0; i < opened.length; i++) {
|
|
302
|
+
if (reply[key] === opened[i].value) {
|
|
303
|
+
reply[key] = opened[i].sealed;
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
|
|
212
310
|
function claimSegmentContext(segmentConfig, context) {
|
|
213
311
|
var orderKeys = readSignedOrder(context);
|
|
214
312
|
if (orderKeys) restoreOrder(context, orderKeys);
|
|
215
313
|
dropUnsignedResults(segmentConfig, context, orderKeys);
|
|
314
|
+
openSealedResults(context);
|
|
216
315
|
stripForeignControlKeys(segmentConfig, context);
|
|
217
316
|
__incomingOrders.set(context, Object.keys(context).filter(function(k) { return !isControlKey(k); }));
|
|
218
317
|
utils.claimSegmentContext(segmentConfig, context);
|
|
@@ -222,6 +321,13 @@ function claimSegmentContext(segmentConfig, context) {
|
|
|
222
321
|
|
|
223
322
|
function segmentReply(segmentConfig, context, snapshot) {
|
|
224
323
|
var reply = utils.segmentReply(segmentConfig, context, snapshot);
|
|
324
|
+
resealRelayedResults(context, reply);
|
|
325
|
+
var credentialIds = utils.credentialResultNodeIds(segmentConfig);
|
|
326
|
+
Object.keys(credentialIds).forEach(function(id) {
|
|
327
|
+
if (context[id] === undefined) return;
|
|
328
|
+
var sealed = sealResult(context[id]);
|
|
329
|
+
if (sealed) reply[id] = sealed;
|
|
330
|
+
});
|
|
225
331
|
var sigs = {};
|
|
226
332
|
var incoming = context.__sig && typeof context.__sig === 'object' && !Array.isArray(context.__sig) ? context.__sig : {};
|
|
227
333
|
Object.keys(incoming).forEach(function(id) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server-runtime-code.js","sourceRoot":"","sources":["../../src/server-runtime-code.ts"],"names":[],"mappings":";;;AAAA
|
|
1
|
+
{"version":3,"file":"server-runtime-code.js","sourceRoot":"","sources":["../../src/server-runtime-code.ts"],"names":[],"mappings":";;;AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACI,MAAM,yBAAyB,GAAG,GAAW,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2WtD,CAAA;AA3WY,QAAA,yBAAyB,6BA2WrC"}
|