heimdall-tide 0.1.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/LICENSE +334 -0
- package/README.md +3 -0
- package/dist/cjs/enclaves/ApprovalEnclave.d.ts +12 -0
- package/dist/cjs/enclaves/ApprovalEnclave.js +57 -0
- package/dist/cjs/enclaves/ApprovalEnclave.js.map +1 -0
- package/dist/cjs/enclaves/RequestEnclave.d.ts +38 -0
- package/dist/cjs/enclaves/RequestEnclave.js +204 -0
- package/dist/cjs/enclaves/RequestEnclave.js.map +1 -0
- package/dist/cjs/heimdall.d.ts +46 -0
- package/dist/cjs/heimdall.js +168 -0
- package/dist/cjs/heimdall.js.map +1 -0
- package/dist/cjs/index.d.ts +4 -0
- package/dist/cjs/index.js +8 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/wrapper.d.ts +16 -0
- package/dist/cjs/wrapper.js +232 -0
- package/dist/cjs/wrapper.js.map +1 -0
- package/dist/esm/enclaves/ApprovalEnclave.d.ts +12 -0
- package/dist/esm/enclaves/ApprovalEnclave.js +53 -0
- package/dist/esm/enclaves/ApprovalEnclave.js.map +1 -0
- package/dist/esm/enclaves/RequestEnclave.d.ts +38 -0
- package/dist/esm/enclaves/RequestEnclave.js +200 -0
- package/dist/esm/enclaves/RequestEnclave.js.map +1 -0
- package/dist/esm/heimdall.d.ts +46 -0
- package/dist/esm/heimdall.js +164 -0
- package/dist/esm/heimdall.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +5 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/wrapper.d.ts +16 -0
- package/dist/esm/wrapper.js +225 -0
- package/dist/esm/wrapper.js.map +1 -0
- package/heimdall-tide-0.1.0.tgz +0 -0
- package/package.json +44 -0
- package/src/enclaves/ApprovalEnclave.ts +63 -0
- package/src/enclaves/RequestEnclave.ts +237 -0
- package/src/heimdall.ts +204 -0
- package/src/index.ts +4 -0
- package/src/wrapper.ts +258 -0
- package/tsconfig.cjs.json +9 -0
- package/tsconfig.esm.json +10 -0
- package/tsconfig.json +9 -0
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
export const version = "1";
|
|
2
|
+
export function wrapper(arr) {
|
|
3
|
+
// If array is only Uint8Arrays - create a TideMemory out of it
|
|
4
|
+
// If there is any entry in an array that is another array
|
|
5
|
+
// -> Go inside that array and repeat the process
|
|
6
|
+
if (arr.every(a => a instanceof Uint8Array))
|
|
7
|
+
return TideMemory.CreateFromArray(arr);
|
|
8
|
+
else {
|
|
9
|
+
// Go through each entry
|
|
10
|
+
arr.forEach((a) => {
|
|
11
|
+
// If the entry is an array, apply the wappa on it
|
|
12
|
+
if (Array.isArray(a)) {
|
|
13
|
+
// Reassign the value of the entry -> to the serialized wrapper
|
|
14
|
+
a = wrapper(a);
|
|
15
|
+
}
|
|
16
|
+
else if (a["value"]) {
|
|
17
|
+
// Let's check if is a number, boolean or Uint8Array. If none of those, it'll be null
|
|
18
|
+
const res = encode(a["value"]);
|
|
19
|
+
if (res) {
|
|
20
|
+
// serialized correctly
|
|
21
|
+
a = res;
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
if (typeof a["value"] == "string") {
|
|
25
|
+
// Serialize it into Uint8Array
|
|
26
|
+
if (!a["encoding"]) {
|
|
27
|
+
// No encoding provided
|
|
28
|
+
// Let's default to UTF-8
|
|
29
|
+
a = encodeStr(a["value"], "UTF-8");
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
a = encodeStr(a["value"], a["encoding"]);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else
|
|
36
|
+
throw 'Unsupported type';
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
else
|
|
40
|
+
throw 'Unexpected format';
|
|
41
|
+
});
|
|
42
|
+
if (arr.every(a => a instanceof Uint8Array))
|
|
43
|
+
return TideMemory.CreateFromArray(arr); // Check to make sure everything was serialized correctly from the wappa
|
|
44
|
+
else
|
|
45
|
+
throw 'There was an error encoding all your values';
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export function encodeStr(str, enc) {
|
|
49
|
+
switch (enc) {
|
|
50
|
+
case "UTF-8":
|
|
51
|
+
return new TextEncoder().encode(str);
|
|
52
|
+
case "HEX":
|
|
53
|
+
// 1) Strip 0x prefix
|
|
54
|
+
let normalized = str.replace(/^0x/i, "");
|
|
55
|
+
// treat empty as invalid
|
|
56
|
+
if (normalized.length === 0) {
|
|
57
|
+
throw new Error("Empty hex string");
|
|
58
|
+
}
|
|
59
|
+
// 2) Pad odd length
|
|
60
|
+
if (normalized.length % 2 !== 0) {
|
|
61
|
+
normalized = "0" + normalized;
|
|
62
|
+
}
|
|
63
|
+
// 3) Validate
|
|
64
|
+
if (!/^[0-9A-Fa-f]+$/.test(normalized)) {
|
|
65
|
+
throw new Error("Invalid hex string");
|
|
66
|
+
}
|
|
67
|
+
// 4) Parse into bytes
|
|
68
|
+
const byteCount = normalized.length / 2;
|
|
69
|
+
const out = new Uint8Array(byteCount);
|
|
70
|
+
for (let i = 0; i < byteCount; i++) {
|
|
71
|
+
out[i] = Number.parseInt(normalized.slice(i * 2, i * 2 + 2), 16);
|
|
72
|
+
}
|
|
73
|
+
return out;
|
|
74
|
+
case "B64":
|
|
75
|
+
const binaryString = atob(str);
|
|
76
|
+
const len = binaryString.length;
|
|
77
|
+
const bytes = new Uint8Array(len);
|
|
78
|
+
for (let i = 0; i < len; i++) {
|
|
79
|
+
bytes[i] = binaryString.charCodeAt(i);
|
|
80
|
+
}
|
|
81
|
+
return bytes;
|
|
82
|
+
case "B64URL":
|
|
83
|
+
// 1) Replace URL-safe chars with standard Base64 chars
|
|
84
|
+
let base64 = str.replace(/-/g, '+').replace(/_/g, '/');
|
|
85
|
+
// 2) Pad with '=' so length is a multiple of 4
|
|
86
|
+
const pad = base64.length % 4;
|
|
87
|
+
if (pad === 2) {
|
|
88
|
+
base64 += '==';
|
|
89
|
+
}
|
|
90
|
+
else if (pad === 3) {
|
|
91
|
+
base64 += '=';
|
|
92
|
+
}
|
|
93
|
+
else if (pad === 1) {
|
|
94
|
+
// This shouldn’t happen for valid Base64-URL, but just in case…
|
|
95
|
+
base64 += '===';
|
|
96
|
+
}
|
|
97
|
+
// 3) Decode to binary string
|
|
98
|
+
const binary = atob(base64);
|
|
99
|
+
// 4) Convert to Uint8Array
|
|
100
|
+
const ulen = binary.length;
|
|
101
|
+
const ubytes = new Uint8Array(ulen);
|
|
102
|
+
for (let i = 0; i < ulen; i++) {
|
|
103
|
+
ubytes[i] = binary.charCodeAt(i);
|
|
104
|
+
}
|
|
105
|
+
return ubytes;
|
|
106
|
+
default:
|
|
107
|
+
// catches anything else (should never happen)
|
|
108
|
+
throw new TypeError(`Unsupported encoding: ${enc}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
export function encode(data) {
|
|
112
|
+
switch (typeof data) {
|
|
113
|
+
case 'number':
|
|
114
|
+
const buffer = new ArrayBuffer(4);
|
|
115
|
+
const view = new DataView(buffer);
|
|
116
|
+
view.setUint32(0, data, true);
|
|
117
|
+
return new Uint8Array(buffer);
|
|
118
|
+
case 'boolean':
|
|
119
|
+
return new Uint8Array([data ? 1 : 0]);
|
|
120
|
+
case 'object':
|
|
121
|
+
// since a Uint8Array is an object at runtime, we need to check it here
|
|
122
|
+
if (data instanceof Uint8Array) {
|
|
123
|
+
return new Uint8Array(data.slice(0));
|
|
124
|
+
}
|
|
125
|
+
// if we fall through, it wasn't one of our allowed types
|
|
126
|
+
throw new TypeError(`Unsupported object type: ${data}`);
|
|
127
|
+
default:
|
|
128
|
+
// catches anything else (should never happen)
|
|
129
|
+
return undefined;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Tide Memory Object helper functions from tide-js
|
|
133
|
+
export class TideMemory extends Uint8Array {
|
|
134
|
+
static CreateFromArray(datas) {
|
|
135
|
+
const length = datas.reduce((sum, next) => sum + next.length, 0);
|
|
136
|
+
const mem = this.Create(datas[0], length);
|
|
137
|
+
for (let i = 1; i < datas.length; i++) {
|
|
138
|
+
mem.WriteValue(i, datas[i]);
|
|
139
|
+
}
|
|
140
|
+
return mem;
|
|
141
|
+
}
|
|
142
|
+
static Create(initialValue, totalLength, version = 1) {
|
|
143
|
+
if (totalLength < initialValue.length + 4) {
|
|
144
|
+
throw new Error("Not enough space to allocate requested data. Make sure to request more space in totalLength than length of InitialValue plus 4 bytes for length.");
|
|
145
|
+
}
|
|
146
|
+
// Total buffer length is 4 (version) + totalLength
|
|
147
|
+
const bufferLength = 4 + totalLength;
|
|
148
|
+
const buffer = new TideMemory(bufferLength);
|
|
149
|
+
const dataView = new DataView(buffer.buffer);
|
|
150
|
+
// Write version at position 0 (4 bytes)
|
|
151
|
+
dataView.setInt32(0, version, true); // true for little-endian
|
|
152
|
+
let dataLocationIndex = 4;
|
|
153
|
+
// Write data length of initialValue at position 4 (4 bytes)
|
|
154
|
+
dataView.setInt32(dataLocationIndex, initialValue.length, true);
|
|
155
|
+
dataLocationIndex += 4;
|
|
156
|
+
// Write initialValue starting from position 8
|
|
157
|
+
buffer.set(initialValue, dataLocationIndex);
|
|
158
|
+
return buffer;
|
|
159
|
+
}
|
|
160
|
+
WriteValue(index, value) {
|
|
161
|
+
if (index < 0)
|
|
162
|
+
throw new Error("Index cannot be less than 0");
|
|
163
|
+
if (index === 0)
|
|
164
|
+
throw new Error("Use CreateTideMemory to set value at index 0");
|
|
165
|
+
if (this.length < 4 + value.length)
|
|
166
|
+
throw new Error("Could not write to memory. Memory too small for this value");
|
|
167
|
+
const dataView = new DataView(this.buffer);
|
|
168
|
+
let dataLocationIndex = 4; // Start after the version number
|
|
169
|
+
// Navigate through existing data segments
|
|
170
|
+
for (let i = 0; i < index; i++) {
|
|
171
|
+
if (dataLocationIndex + 4 > this.length) {
|
|
172
|
+
throw new RangeError("Index out of range.");
|
|
173
|
+
}
|
|
174
|
+
// Read data length at current position
|
|
175
|
+
const nextDataLength = dataView.getInt32(dataLocationIndex, true);
|
|
176
|
+
dataLocationIndex += 4;
|
|
177
|
+
dataLocationIndex += nextDataLength;
|
|
178
|
+
}
|
|
179
|
+
// Check if there's enough space to write the value
|
|
180
|
+
if (dataLocationIndex + 4 + value.length > this.length) {
|
|
181
|
+
throw new RangeError("Not enough space to write value");
|
|
182
|
+
}
|
|
183
|
+
// Check if data has already been written to this index
|
|
184
|
+
const existingLength = dataView.getInt32(dataLocationIndex, true);
|
|
185
|
+
if (existingLength !== 0) {
|
|
186
|
+
throw new Error("Data has already been written to this index");
|
|
187
|
+
}
|
|
188
|
+
// Write data length of value at current position
|
|
189
|
+
dataView.setInt32(dataLocationIndex, value.length, true);
|
|
190
|
+
dataLocationIndex += 4;
|
|
191
|
+
// Write value starting from current position
|
|
192
|
+
this.set(value, dataLocationIndex);
|
|
193
|
+
}
|
|
194
|
+
GetValue(index) {
|
|
195
|
+
// 'a' should be an ArrayBuffer or Uint8Array
|
|
196
|
+
if (this.length < 4) {
|
|
197
|
+
throw new Error("Insufficient data to read.");
|
|
198
|
+
}
|
|
199
|
+
// Create a DataView for reading integers in little-endian format
|
|
200
|
+
const dataView = new DataView(this.buffer, this.byteOffset, this.byteLength);
|
|
201
|
+
// Optional: Read the version if needed
|
|
202
|
+
// const version = dataView.getInt32(0, true);
|
|
203
|
+
let dataLocationIndex = 4;
|
|
204
|
+
for (let i = 0; i < index; i++) {
|
|
205
|
+
// Check if there's enough data to read the length of the next segment
|
|
206
|
+
if (dataLocationIndex + 4 > this.length) {
|
|
207
|
+
throw new RangeError("Index out of range.");
|
|
208
|
+
}
|
|
209
|
+
const nextDataLength = dataView.getInt32(dataLocationIndex, true);
|
|
210
|
+
dataLocationIndex += 4 + nextDataLength;
|
|
211
|
+
}
|
|
212
|
+
// Check if there's enough data to read the length of the final segment
|
|
213
|
+
if (dataLocationIndex + 4 > this.length) {
|
|
214
|
+
throw new RangeError("Index out of range.");
|
|
215
|
+
}
|
|
216
|
+
const finalDataLength = dataView.getInt32(dataLocationIndex, true);
|
|
217
|
+
dataLocationIndex += 4;
|
|
218
|
+
// Check if the final data segment is within bounds
|
|
219
|
+
if (dataLocationIndex + finalDataLength > this.length) {
|
|
220
|
+
throw new RangeError("Index out of range.");
|
|
221
|
+
}
|
|
222
|
+
return this.subarray(dataLocationIndex, dataLocationIndex + finalDataLength);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=wrapper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapper.js","sourceRoot":"","sources":["../../src/wrapper.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "heimdall-tide",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SDK for communicating with a Tide Enclave",
|
|
5
|
+
"main": "dist/cjs/index.js",
|
|
6
|
+
"module": "dist/esm/index.js",
|
|
7
|
+
"typings": "dist/esm/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/esm/index.js",
|
|
11
|
+
"require": "./dist/cjs/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./enclaves/ApprovalEnclave": {
|
|
14
|
+
"import": "./dist/esm/enclaves/ApprovalEnclave.js",
|
|
15
|
+
"require": "./dist/cjs/enclaves/ApprovalEnclave.js"
|
|
16
|
+
},
|
|
17
|
+
"./enclaves/RequestEnclave": {
|
|
18
|
+
"import": "./dist/esm/enclaves/RequestEnclave.js",
|
|
19
|
+
"require": "./dist/cjs/enclaves/RequestEnclave.js"
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build:cjs": "tsc -p tsconfig.cjs.json",
|
|
24
|
+
"build:esm": "tsc -p tsconfig.esm.json",
|
|
25
|
+
"build": "npm run build:cjs && npm run build:esm"
|
|
26
|
+
},
|
|
27
|
+
"repository": {
|
|
28
|
+
"type": "git",
|
|
29
|
+
"url": "git+https://github.com/tide-foundation/heimdall.git"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"tide"
|
|
33
|
+
],
|
|
34
|
+
"author": "Tide",
|
|
35
|
+
"license": "ISC",
|
|
36
|
+
"types": "./heimdall.d.ts",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/tide-foundation/heimdall/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/tide-foundation/heimdall#readme",
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"typescript": "^5.8.3"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import {Heimdall, windowType} from "../heimdall";
|
|
2
|
+
|
|
3
|
+
export class ApprovalEnclave extends Heimdall<ApprovalEnclave>{
|
|
4
|
+
name: string = "approval";
|
|
5
|
+
_windowType: windowType = windowType.Popup;
|
|
6
|
+
private acceptedAdminIds: string[];
|
|
7
|
+
enclaveUrl: URL;
|
|
8
|
+
private initDone: Promise<any>;
|
|
9
|
+
|
|
10
|
+
init(data: string[], enclaveUrl: string): ApprovalEnclave {
|
|
11
|
+
this.acceptedAdminIds = data;
|
|
12
|
+
this.enclaveUrl = new URL(enclaveUrl);
|
|
13
|
+
this.initDone = this.open();
|
|
14
|
+
return this;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async getAuthorizerAuthentication() {
|
|
18
|
+
await this.initDone;
|
|
19
|
+
// ready to accept reply
|
|
20
|
+
const pre_response = this.recieve("authentication");
|
|
21
|
+
|
|
22
|
+
// send to enclave
|
|
23
|
+
this.send({
|
|
24
|
+
type: "authentication",
|
|
25
|
+
message: "pretty please"
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// wait for response - this does not mean that enclave it closed, just that the admin has responded to the approval request from the enclave
|
|
29
|
+
return await pre_response;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
async getAuthorizerApproval(draftToApprove, modelId, expiry, encoding = "bytes", authflow = "") {
|
|
34
|
+
await this.initDone;
|
|
35
|
+
// ready to accept reply
|
|
36
|
+
const pre_response = this.recieve("approval");
|
|
37
|
+
|
|
38
|
+
// send to enclave
|
|
39
|
+
this.send({
|
|
40
|
+
type: "approval",
|
|
41
|
+
message: {
|
|
42
|
+
draftToAuthorize: {
|
|
43
|
+
data: draftToApprove,
|
|
44
|
+
encoding: encoding
|
|
45
|
+
},
|
|
46
|
+
modelId: modelId,
|
|
47
|
+
expiry: expiry,
|
|
48
|
+
authflow: authflow
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
// wait for response - this does not mean that enclave it closed, just that the admin has responded to the approval request from the enclave
|
|
53
|
+
return await pre_response;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
getOrkUrl() {
|
|
57
|
+
// how to create approval ork url for openinging enclave?
|
|
58
|
+
this.enclaveUrl.searchParams.set("type", "approval");
|
|
59
|
+
this.enclaveUrl.searchParams.set("acceptedIds", JSON.stringify(this.acceptedAdminIds));
|
|
60
|
+
return this.enclaveUrl;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { Heimdall, windowType } from "../heimdall";
|
|
2
|
+
import { TideMemory } from "../wrapper";
|
|
3
|
+
|
|
4
|
+
interface HiddenInit{
|
|
5
|
+
doken: string;
|
|
6
|
+
/**
|
|
7
|
+
* @returns A refresh doken for Heimdall
|
|
8
|
+
*/
|
|
9
|
+
dokenRefreshCallback: () => Promise<string> | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* @returns A function that re authenticates the current user from the client. (Used to update their session key on Identity System). Returns a new doken too.
|
|
12
|
+
*/
|
|
13
|
+
requireReloginCallback: () => Promise<string>;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export class RequestEnclave extends Heimdall<RequestEnclave>{
|
|
17
|
+
private doken: string;
|
|
18
|
+
private dokenRefreshCallback: () => Promise<string> | undefined;
|
|
19
|
+
private requireReloginCallback: () => Promise<string>;
|
|
20
|
+
|
|
21
|
+
_windowType: windowType = windowType.Hidden;
|
|
22
|
+
|
|
23
|
+
private initDone: Promise<any> = this.recieve("init done");
|
|
24
|
+
|
|
25
|
+
init(data: HiddenInit): RequestEnclave {
|
|
26
|
+
if(!data.doken) throw 'Doken not provided';
|
|
27
|
+
|
|
28
|
+
this.doken = data.doken;
|
|
29
|
+
this.dokenRefreshCallback = data.dokenRefreshCallback;
|
|
30
|
+
this.requireReloginCallback = data.requireReloginCallback;
|
|
31
|
+
|
|
32
|
+
this.recieve("hidden enclave").then((data) => this.handleHiddenEnclaveResponse(data));
|
|
33
|
+
|
|
34
|
+
this.open().then((success: boolean) => {
|
|
35
|
+
if(success){
|
|
36
|
+
this.send({
|
|
37
|
+
type: "init",
|
|
38
|
+
message: {
|
|
39
|
+
doken: this.doken
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
}else throw 'Error opening enclave';
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
async handleHiddenEnclaveResponse(msg: any){
|
|
49
|
+
// Below is the session key mismatch flow that was implemented but then it was decided a basic relogin was more elegent
|
|
50
|
+
// Keeping it though because it is nearly identical to the flow where a tide user delegates a token to another tide user
|
|
51
|
+
// This would require the second tide user to sign a new delegated token with their current session key
|
|
52
|
+
// This would be gold in a cvk scenario
|
|
53
|
+
// if(msg == "session key mismatch" && this._windowType == windowType.Hidden){
|
|
54
|
+
// this.initDone = this.recieve("init done"); // await the REOPENED HIDDEN ENCLAVE INIT DONE SIGNAL
|
|
55
|
+
// // looks like the hidden iframe has not allowed data to be stored on the browser OR the session key is mismatched with whats on the enclave vs doken
|
|
56
|
+
// // either way we gotta get a doken with the appropriate session key
|
|
57
|
+
|
|
58
|
+
// // Close the hidden enclave
|
|
59
|
+
// this.close();
|
|
60
|
+
|
|
61
|
+
// // We're now going to open the request enclave as a popup with the mismatched doken
|
|
62
|
+
// // The page should recognise the doken is mismatched, generate a new one, then close
|
|
63
|
+
// this._windowType = windowType.Popup;
|
|
64
|
+
|
|
65
|
+
// // open popup
|
|
66
|
+
// await this.open();
|
|
67
|
+
// // send doken to refresh
|
|
68
|
+
// this.send({
|
|
69
|
+
// type: "init",
|
|
70
|
+
// message:{
|
|
71
|
+
// doken: this.doken
|
|
72
|
+
// }
|
|
73
|
+
// });
|
|
74
|
+
// // wait for new doken
|
|
75
|
+
// const resp = await this.recieve("refreshed doken");
|
|
76
|
+
// this.doken = resp.doken;
|
|
77
|
+
// if(this.requireReloginCallback) this.requireReloginCallback();
|
|
78
|
+
|
|
79
|
+
// // close pop up enclave
|
|
80
|
+
// this.close();
|
|
81
|
+
|
|
82
|
+
// // reset page to hidden iframe
|
|
83
|
+
// this._windowType = windowType.Hidden;
|
|
84
|
+
// // open hidden iframe
|
|
85
|
+
// this.open().then((success: boolean) => {
|
|
86
|
+
// if(success){
|
|
87
|
+
// this.send({
|
|
88
|
+
// type: "init",
|
|
89
|
+
// message: {
|
|
90
|
+
// doken: this.doken
|
|
91
|
+
// }
|
|
92
|
+
// });
|
|
93
|
+
// }else throw 'Error opening enclave';
|
|
94
|
+
// });
|
|
95
|
+
|
|
96
|
+
// }
|
|
97
|
+
if(msg == "session key mismatch"){
|
|
98
|
+
this.requireReloginCallback(); // should initiate a full client page reload, killing this
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this.recieve("hidden enclave").then((data) => this.handleHiddenEnclaveResponse(data));
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
getOrkUrl(): URL {
|
|
105
|
+
// construct ork url
|
|
106
|
+
const url = new URL(this.enclaveOrigin);
|
|
107
|
+
|
|
108
|
+
// Set hidden status
|
|
109
|
+
url.searchParams.set("hidden", this._windowType == windowType.Hidden ? "true" : "false");
|
|
110
|
+
|
|
111
|
+
// Set vendor public
|
|
112
|
+
url.searchParams.set("vendorId", this.vendorId);
|
|
113
|
+
|
|
114
|
+
// Set client origin
|
|
115
|
+
url.searchParams.set("origin", encodeURIComponent(window.location.origin));
|
|
116
|
+
|
|
117
|
+
// Set client origin signature (by vendor)
|
|
118
|
+
url.searchParams.set("originsig", encodeURIComponent(this.signed_client_origin));
|
|
119
|
+
|
|
120
|
+
// Set voucher url
|
|
121
|
+
url.searchParams.set("voucherURL", encodeURIComponent(this.voucherURL));
|
|
122
|
+
|
|
123
|
+
// Set requestsed enclave
|
|
124
|
+
url.searchParams.set("type", "request");
|
|
125
|
+
|
|
126
|
+
return url;
|
|
127
|
+
}
|
|
128
|
+
checkEnclaveOpen(){
|
|
129
|
+
if(this.enclaveClosed()){
|
|
130
|
+
// Enclave was closed!
|
|
131
|
+
// We need to reopen the enclave and await the init again
|
|
132
|
+
this.initDone = this.recieve("init done");
|
|
133
|
+
this.open().then((success: boolean) => {
|
|
134
|
+
if(success){
|
|
135
|
+
this.send({
|
|
136
|
+
type: "init",
|
|
137
|
+
message:{
|
|
138
|
+
doken: this.doken
|
|
139
|
+
}
|
|
140
|
+
});
|
|
141
|
+
}else throw 'Error opening enclave';
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async execute(data: TideMemory): Promise<Uint8Array[]>{
|
|
147
|
+
this.checkEnclaveOpen();
|
|
148
|
+
await this.initDone;
|
|
149
|
+
const pre_resp = this.recieve("sign request completed");
|
|
150
|
+
this.send({
|
|
151
|
+
type: "request",
|
|
152
|
+
message:{
|
|
153
|
+
flow: "sign",
|
|
154
|
+
request: data,
|
|
155
|
+
}
|
|
156
|
+
})
|
|
157
|
+
const resp = await pre_resp;
|
|
158
|
+
if(!Array.isArray(resp)) throw 'Expecting request completed data to be an array, not' + resp;
|
|
159
|
+
if(!resp.every((d: any) => d instanceof Uint8Array)) throw 'Expecting all entries in response to be Uint8Arrays';
|
|
160
|
+
return resp;
|
|
161
|
+
}
|
|
162
|
+
async decrypt(data: decryptRequest): Promise<Uint8Array[]>{
|
|
163
|
+
this.checkEnclaveOpen();
|
|
164
|
+
await this.initDone;
|
|
165
|
+
const pre_resp = this.recieve("decrypt request completed");
|
|
166
|
+
this.send({
|
|
167
|
+
type: "request",
|
|
168
|
+
message:{
|
|
169
|
+
flow: "decrypt",
|
|
170
|
+
request: data
|
|
171
|
+
}
|
|
172
|
+
})
|
|
173
|
+
const resp = await pre_resp;
|
|
174
|
+
if(!Array.isArray(resp)) throw 'Expecting request completed data to be an array, not' + resp;
|
|
175
|
+
if(!resp.every((d: any) => d instanceof Uint8Array)) throw 'Expecting all entries in response to be Uint8Arrays';
|
|
176
|
+
return resp;
|
|
177
|
+
}
|
|
178
|
+
async encrypt(data: encryptRequest): Promise<Uint8Array[]>{
|
|
179
|
+
this.checkEnclaveOpen();
|
|
180
|
+
await this.initDone;
|
|
181
|
+
const pre_resp = this.recieve("encrypt request completed");
|
|
182
|
+
this.send({
|
|
183
|
+
type: "request",
|
|
184
|
+
message: {
|
|
185
|
+
flow: "encrypt",
|
|
186
|
+
request: data
|
|
187
|
+
}
|
|
188
|
+
})
|
|
189
|
+
const resp = await pre_resp;
|
|
190
|
+
if(!Array.isArray(resp)) throw 'Expecting request completed data to be an array, not' + resp;
|
|
191
|
+
if(!resp.every((d: any) => d instanceof Uint8Array)) throw 'Expecting all entries in response to be Uint8Arrays';
|
|
192
|
+
return resp;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
async updateDoken(doken: string){
|
|
196
|
+
this.doken = doken;
|
|
197
|
+
this.send({
|
|
198
|
+
type: "doken refresh",
|
|
199
|
+
message:{
|
|
200
|
+
doken: this.doken
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
async onerror(data: any) {
|
|
206
|
+
if(typeof data.message === "string"){
|
|
207
|
+
switch(data.message){
|
|
208
|
+
case "expired":
|
|
209
|
+
if(!this.dokenRefreshCallback){
|
|
210
|
+
console.error("[HEIMDALL] Doken on enclave has expired but there is no Doken Refresh Callback registered");
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
console.log("[HEIMDALL] Refreshing doken");
|
|
214
|
+
this.doken = await this.dokenRefreshCallback();
|
|
215
|
+
this.send({
|
|
216
|
+
type: "doken refresh",
|
|
217
|
+
message:{
|
|
218
|
+
doken: this.doken
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
break;
|
|
222
|
+
default:
|
|
223
|
+
this.close();
|
|
224
|
+
throw new Error("[HEIMDALL] Recieved enclave error: " + data.message);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
interface decryptRequest{
|
|
231
|
+
encrypted: Uint8Array;
|
|
232
|
+
tags: string[]
|
|
233
|
+
}
|
|
234
|
+
interface encryptRequest{
|
|
235
|
+
data: Uint8Array;
|
|
236
|
+
tags: string[]
|
|
237
|
+
}
|