@api-client/core 0.3.2 → 0.3.5
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/build/browser.d.ts +1 -0
- package/build/browser.js +1 -0
- package/build/browser.js.map +1 -1
- package/build/index.d.ts +1 -1
- package/build/index.js +1 -1
- package/build/index.js.map +1 -1
- package/build/src/models/ErrorResponse.d.ts +5 -4
- package/build/src/models/ErrorResponse.js +18 -5
- package/build/src/models/ErrorResponse.js.map +1 -1
- package/build/src/models/SerializableError.d.ts +30 -0
- package/build/src/models/SerializableError.js +63 -0
- package/build/src/models/SerializableError.js.map +1 -0
- package/build/src/runtime/http-engine/ArcEngine.js +8 -4
- package/build/src/runtime/http-engine/ArcEngine.js.map +1 -1
- package/build/src/runtime/http-engine/HttpEngine.d.ts +3 -3
- package/build/src/runtime/http-engine/HttpEngine.js +3 -3
- package/build/src/runtime/http-engine/HttpEngine.js.map +1 -1
- package/build/src/runtime/http-engine/NodeEngine.js +9 -4
- package/build/src/runtime/http-engine/NodeEngine.js.map +1 -1
- package/build/src/runtime/http-engine/NodeEngineDirect.js +8 -2
- package/build/src/runtime/http-engine/NodeEngineDirect.js.map +1 -1
- package/build/src/runtime/node/ProjectRunner.d.ts +2 -2
- package/build/src/runtime/node/ProjectRunner.js +9 -2
- package/build/src/runtime/node/ProjectRunner.js.map +1 -1
- package/build/src/runtime/store/StoreSdk.js +10 -15
- package/build/src/runtime/store/StoreSdk.js.map +1 -1
- package/package.json +1 -1
- package/src/data/DataReader.ts +11 -0
- package/src/data/DataUtils.ts +108 -0
- package/src/data/JmesparthReader.ts +26 -0
- package/src/data/Json2Xml.ts +190 -0
- package/src/data/JsonReader.ts +41 -0
- package/src/data/PayloadPointer.ts +48 -0
- package/src/data/RequestDataExtractor.ts +133 -0
- package/src/data/UrlEncodedReader.ts +20 -0
- package/src/data/XmlReader.ts +103 -0
- package/src/events/BaseEvents.ts +259 -0
- package/src/events/CustomEvent.ts +27 -0
- package/src/events/EventTypes.ts +19 -0
- package/src/events/Events.ts +19 -0
- package/src/events/authorization/AuthorizationEventTypes.ts +22 -0
- package/src/events/authorization/AuthorizationEvents.ts +61 -0
- package/src/events/cookies/CookieEventTypes.ts +13 -0
- package/src/events/cookies/CookieEvents.ts +157 -0
- package/src/events/encryption/EncryptionEventTypes.ts +4 -0
- package/src/events/encryption/EncryptionEvents.ts +51 -0
- package/src/events/environment/EnvironmentEventTypes.ts +3 -0
- package/src/events/environment/EnvironmentEvents.ts +24 -0
- package/src/events/models/ClientCertificateEvents.ts +87 -0
- package/src/events/models/ModelEventTypes.ts +47 -0
- package/src/events/models/ModelEvents.ts +7 -0
- package/src/events/models/ProjectEvents.ts +331 -0
- package/src/events/process/ProcessEventTypes.ts +5 -0
- package/src/events/process/ProcessEvents.ts +76 -0
- package/src/events/readme.md +22 -0
- package/src/events/reporting/ReportingEventTypes.ts +3 -0
- package/src/events/reporting/ReportingEvents.ts +28 -0
- package/src/events/telemetry/TelemetryEventTypes.ts +10 -0
- package/src/events/telemetry/TelemetryEvents.ts +156 -0
- package/src/lib/cookies/Cookie.ts +312 -0
- package/src/lib/cookies/Cookies.ts +326 -0
- package/src/lib/cookies/Utils.ts +168 -0
- package/src/lib/headers/Headers.ts +219 -0
- package/src/lib/logging/DefaultLogger.ts +19 -0
- package/src/lib/logging/DummyLogger.ts +21 -0
- package/src/lib/logging/Logger.ts +16 -0
- package/src/lib/transformers/PayloadSerializer.ts +332 -0
- package/src/lib/transformers/Utils.ts +18 -0
- package/src/lib/uuid.ts +40 -0
- package/src/mocking/LegacyInterfaces.ts +52 -0
- package/src/mocking/LegacyMock.ts +37 -0
- package/src/mocking/legacy/Authorization.ts +39 -0
- package/src/mocking/legacy/Certificates.ts +145 -0
- package/src/mocking/legacy/Cookies.ts +51 -0
- package/src/mocking/legacy/HostRules.ts +43 -0
- package/src/mocking/legacy/Http.ts +236 -0
- package/src/mocking/legacy/HttpResponse.ts +106 -0
- package/src/mocking/legacy/RestApi.ts +68 -0
- package/src/mocking/legacy/Urls.ts +44 -0
- package/src/mocking/legacy/Variables.ts +53 -0
- package/src/models/ArcResponse.ts +166 -0
- package/src/models/Authorization.ts +481 -0
- package/src/models/AuthorizationData.ts +60 -0
- package/src/models/Backend.ts +107 -0
- package/src/models/ClientCertificate.ts +68 -0
- package/src/models/Environment.ts +279 -0
- package/src/models/ErrorResponse.ts +113 -0
- package/src/models/HistoryIndex.ts +76 -0
- package/src/models/HistoryRequest.ts +28 -0
- package/src/models/HostRule.ts +163 -0
- package/src/models/HttpCookie.ts +285 -0
- package/src/models/HttpProject.ts +1294 -0
- package/src/models/HttpProjectListItem.ts +23 -0
- package/src/models/HttpRequest.ts +124 -0
- package/src/models/HttpResponse.ts +143 -0
- package/src/models/License.ts +113 -0
- package/src/models/ProjectDefinitionProperty.ts +40 -0
- package/src/models/ProjectFolder.ts +439 -0
- package/src/models/ProjectItem.ts +135 -0
- package/src/models/ProjectParent.ts +113 -0
- package/src/models/ProjectRequest.ts +277 -0
- package/src/models/ProjectSchema.ts +202 -0
- package/src/models/Property.ts +423 -0
- package/src/models/Provider.ts +98 -0
- package/src/models/README.md +20 -0
- package/src/models/Request.ts +452 -0
- package/src/models/RequestActions.ts +163 -0
- package/src/models/RequestAuthorization.ts +115 -0
- package/src/models/RequestConfig.ts +317 -0
- package/src/models/RequestLog.ts +159 -0
- package/src/models/RequestTime.ts +108 -0
- package/src/models/RequestUiMeta.ts +258 -0
- package/src/models/RequestsSize.ts +65 -0
- package/src/models/ResponseAuthorization.ts +104 -0
- package/src/models/ResponseRedirect.ts +158 -0
- package/src/models/RevisionInfo.ts +37 -0
- package/src/models/SentRequest.ts +125 -0
- package/src/models/SerializableError.ts +80 -0
- package/src/models/SerializablePayload.ts +68 -0
- package/src/models/Server.ts +153 -0
- package/src/models/Thing.ts +110 -0
- package/src/models/Url.ts +90 -0
- package/src/models/User.ts +120 -0
- package/src/models/WebApi.ts +234 -0
- package/src/models/WebApiIndex.ts +122 -0
- package/src/models/Workspace.ts +182 -0
- package/src/models/actions/Action.ts +213 -0
- package/src/models/actions/ActionView.ts +40 -0
- package/src/models/actions/Condition.ts +207 -0
- package/src/models/actions/ConditionView.ts +42 -0
- package/src/models/actions/Enums.ts +29 -0
- package/src/models/actions/RunnableAction.ts +144 -0
- package/src/models/actions/runnable/DeleteCookieAction.ts +113 -0
- package/src/models/actions/runnable/Runnable.ts +9 -0
- package/src/models/actions/runnable/SetCookieAction.ts +216 -0
- package/src/models/actions/runnable/SetVariableAction.ts +81 -0
- package/src/models/legacy/DataExport.ts +172 -0
- package/src/models/legacy/Normalizer.ts +110 -0
- package/src/models/legacy/actions/Actions.ts +269 -0
- package/src/models/legacy/authorization/Authorization.ts +572 -0
- package/src/models/legacy/models/ApiTypes.ts +202 -0
- package/src/models/legacy/models/ArcLegacyProject.ts +39 -0
- package/src/models/legacy/models/AuthData.ts +17 -0
- package/src/models/legacy/models/ClientCertificate.ts +95 -0
- package/src/models/legacy/models/Cookies.ts +52 -0
- package/src/models/legacy/models/HostRule.ts +35 -0
- package/src/models/legacy/models/RestApi.ts +49 -0
- package/src/models/legacy/models/UrlHistory.ts +37 -0
- package/src/models/legacy/models/Variable.ts +43 -0
- package/src/models/legacy/models/base.d.ts +95 -0
- package/src/models/legacy/request/ArcRequest.ts +405 -0
- package/src/models/legacy/request/ArcResponse.ts +177 -0
- package/src/models/legacy/request/HistoryData.ts +47 -0
- package/src/models/legacy/request/Legacy.ts +45 -0
- package/src/models/legacy/request/RequestBody.ts +87 -0
- package/src/models/transformers/ArcDexieTransformer.ts +323 -0
- package/src/models/transformers/ArcLegacyNormalizer.ts +85 -0
- package/src/models/transformers/ArcLegacyTransformer.ts +200 -0
- package/src/models/transformers/ArcPouchTransformer.ts +184 -0
- package/src/models/transformers/BaseTransformer.ts +116 -0
- package/src/models/transformers/ImportUtils.ts +141 -0
- package/src/models/transformers/LegacyDataExportToApiProject.ts +76 -0
- package/src/models/transformers/LegacyExportProcessor.ts +252 -0
- package/src/models/transformers/PostmanBackupTransformer.ts +306 -0
- package/src/models/transformers/PostmanDataTransformer.ts +50 -0
- package/src/models/transformers/PostmanTransformer.ts +106 -0
- package/src/models/transformers/PostmanV21Transformer.ts +311 -0
- package/src/models/transformers/PostmanV2Transformer.ts +308 -0
- package/src/models/transformers/har.ts +865 -0
- package/src/runtime/actions/ActionRunner.ts +83 -0
- package/src/runtime/actions/ConditionRunner.ts +194 -0
- package/src/runtime/actions/RunnableCondition.ts +57 -0
- package/src/runtime/actions/runnable/ActionRunnable.ts +19 -0
- package/src/runtime/actions/runnable/DeleteCookieRunnable.ts +39 -0
- package/src/runtime/actions/runnable/SetCookieRunnable.ts +92 -0
- package/src/runtime/actions/runnable/SetVariableRunnable.ts +53 -0
- package/src/runtime/http-engine/ArcEngine.ts +1068 -0
- package/src/runtime/http-engine/FormData.ts +85 -0
- package/src/runtime/http-engine/HttpEngine.ts +874 -0
- package/src/runtime/http-engine/HttpErrorCodes.ts +270 -0
- package/src/runtime/http-engine/NodeEngine.ts +792 -0
- package/src/runtime/http-engine/NodeEngineDirect.ts +482 -0
- package/src/runtime/http-engine/PayloadSupport.ts +84 -0
- package/src/runtime/http-engine/RequestUtils.ts +164 -0
- package/src/runtime/http-engine/ntlm/Des.ts +345 -0
- package/src/runtime/http-engine/ntlm/MD4.ts +135 -0
- package/src/runtime/http-engine/ntlm/NtlmAuth.ts +186 -0
- package/src/runtime/http-engine/ntlm/NtlmMessage.ts +57 -0
- package/src/runtime/modules/BasicAuthCache.ts +133 -0
- package/src/runtime/modules/ExecutionResponse.ts +4 -0
- package/src/runtime/modules/ModulesRegistry.ts +136 -0
- package/src/runtime/modules/RequestAuthorization.ts +110 -0
- package/src/runtime/modules/RequestCookies.ts +145 -0
- package/src/runtime/node/ProjectRunner.ts +281 -0
- package/src/runtime/node/RequestFactory.ts +422 -0
- package/src/runtime/node/VariablesStore.ts +25 -0
- package/src/runtime/store/StoreSdk.ts +838 -0
- package/src/runtime/variables/Cache.ts +53 -0
- package/src/runtime/variables/EvalFunctions.ts +132 -0
- package/src/runtime/variables/ProjectVariables.ts +6 -0
- package/src/runtime/variables/VariablesProcessor.ts +543 -0
- package/src/runtime/variables/VariablesTokenizer.ts +55 -0
- package/build/src/runtime/http-engine/Errors.d.ts +0 -10
- package/build/src/runtime/http-engine/Errors.js +0 -14
- package/build/src/runtime/http-engine/Errors.js.map +0 -1
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { Des } from './Des.js';
|
|
2
|
+
import { MD4 } from './MD4.js';
|
|
3
|
+
import { NtlmMessage } from './NtlmMessage.js';
|
|
4
|
+
|
|
5
|
+
export interface INtlmAuthConfig {
|
|
6
|
+
domain?: string;
|
|
7
|
+
username: string;
|
|
8
|
+
password: string;
|
|
9
|
+
url: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* A base class for auth methods used in the library.
|
|
14
|
+
* On the base of https://github.com/erlandranvinge/ntlm.js/blob/master/ntlm.js
|
|
15
|
+
*/
|
|
16
|
+
export class NtlmAuth {
|
|
17
|
+
domain: string;
|
|
18
|
+
uid: string;
|
|
19
|
+
passwd: string;
|
|
20
|
+
url: string;
|
|
21
|
+
lmHashedPassword?: string;
|
|
22
|
+
ntHashedPassword?: string;
|
|
23
|
+
|
|
24
|
+
constructor(opts: INtlmAuthConfig) {
|
|
25
|
+
this.domain = opts.domain || '';
|
|
26
|
+
this.uid = opts.username;
|
|
27
|
+
this.passwd = opts.password;
|
|
28
|
+
this.url = opts.url;
|
|
29
|
+
|
|
30
|
+
this.setCredentials();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
createMessage1(hostname: string): NtlmMessage {
|
|
34
|
+
const msg1 = new NtlmMessage();
|
|
35
|
+
msg1.addString('NTLMSSP\0');
|
|
36
|
+
msg1.addByte(1);
|
|
37
|
+
msg1.addString('\0\0\0');
|
|
38
|
+
msg1.addShort(0xb203);
|
|
39
|
+
msg1.addString('\0\0');
|
|
40
|
+
msg1.addShort(this.domain.length);
|
|
41
|
+
msg1.addShort(this.domain.length);
|
|
42
|
+
msg1.addShort(32 + hostname.length);
|
|
43
|
+
msg1.addString('\0\0');
|
|
44
|
+
msg1.addShort(hostname.length);
|
|
45
|
+
msg1.addShort(hostname.length);
|
|
46
|
+
msg1.addShort(32);
|
|
47
|
+
msg1.addString('\0\0');
|
|
48
|
+
msg1.addString(hostname.toUpperCase());
|
|
49
|
+
msg1.addString(this.domain.toUpperCase());
|
|
50
|
+
return msg1;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
getChallenge(data: string): string {
|
|
54
|
+
const msg2 = new NtlmMessage(data);
|
|
55
|
+
if (msg2.getString(0, 8) !== 'NTLMSSP\0') {
|
|
56
|
+
throw new Error('Invalid NTLM response header.');
|
|
57
|
+
}
|
|
58
|
+
if (msg2.getByte(8) !== 2) {
|
|
59
|
+
throw new Error('Invalid NTLM response type.');
|
|
60
|
+
}
|
|
61
|
+
const challenge = msg2.getString(24, 8);
|
|
62
|
+
return challenge;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
createMessage3(challenge: string, hostname: string): NtlmMessage {
|
|
66
|
+
const lmResponse = this.buildResponse(this.lmHashedPassword as string, challenge);
|
|
67
|
+
const ntResponse = this.buildResponse(this.ntHashedPassword as string, challenge);
|
|
68
|
+
const username = this.uid;
|
|
69
|
+
const domain = this.domain;
|
|
70
|
+
const msg3 = new NtlmMessage();
|
|
71
|
+
|
|
72
|
+
msg3.addString('NTLMSSP\0');
|
|
73
|
+
msg3.addByte(3);
|
|
74
|
+
msg3.addString('\0\0\0');
|
|
75
|
+
|
|
76
|
+
msg3.addShort(24); // lmResponse
|
|
77
|
+
msg3.addShort(24);
|
|
78
|
+
msg3.addShort(64 + (domain.length + username.length + hostname.length) * 2);
|
|
79
|
+
msg3.addString('\0\0');
|
|
80
|
+
|
|
81
|
+
msg3.addShort(24); // ntResponse
|
|
82
|
+
msg3.addShort(24);
|
|
83
|
+
msg3.addShort(88 + (domain.length + username.length + hostname.length) * 2);
|
|
84
|
+
msg3.addString('\0\0');
|
|
85
|
+
|
|
86
|
+
msg3.addShort(domain.length * 2); // Domain.
|
|
87
|
+
msg3.addShort(domain.length * 2);
|
|
88
|
+
msg3.addShort(64);
|
|
89
|
+
msg3.addString('\0\0');
|
|
90
|
+
|
|
91
|
+
msg3.addShort(username.length * 2); // Username.
|
|
92
|
+
msg3.addShort(username.length * 2);
|
|
93
|
+
msg3.addShort(64 + domain.length * 2);
|
|
94
|
+
msg3.addShort('\0\0');
|
|
95
|
+
|
|
96
|
+
msg3.addShort(hostname.length * 2); // Hostname.
|
|
97
|
+
msg3.addShort(hostname.length * 2);
|
|
98
|
+
msg3.addShort(64 + (domain.length + username.length) * 2);
|
|
99
|
+
msg3.addString('\0\0');
|
|
100
|
+
|
|
101
|
+
msg3.addString('\0\0\0\0');
|
|
102
|
+
msg3.addShort(112 + (domain.length + username.length + hostname.length) * 2);
|
|
103
|
+
msg3.addString('\0\0');
|
|
104
|
+
msg3.addShort(0x8201);
|
|
105
|
+
msg3.addString('\0\0');
|
|
106
|
+
|
|
107
|
+
msg3.addString(domain.toUpperCase(), true); // "Some" string are passed as UTF-16.
|
|
108
|
+
msg3.addString(username, true);
|
|
109
|
+
msg3.addString(hostname.toUpperCase(), true);
|
|
110
|
+
msg3.addString(lmResponse);
|
|
111
|
+
msg3.addString(ntResponse);
|
|
112
|
+
|
|
113
|
+
return msg3;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
createKey(str: string): string {
|
|
117
|
+
const key56: number[] = [];
|
|
118
|
+
while (str.length < 7) {
|
|
119
|
+
str += '\0';
|
|
120
|
+
}
|
|
121
|
+
str = str.substr(0, 7);
|
|
122
|
+
str.split('').map((c) => {
|
|
123
|
+
key56.push(c.charCodeAt(0));
|
|
124
|
+
});
|
|
125
|
+
const key = [0, 0, 0, 0, 0, 0, 0, 0];
|
|
126
|
+
key[0] = key56[0]; // Convert 56 bit key to 64 bit.
|
|
127
|
+
key[1] = ((key56[0] << 7) & 0xFF) | (key56[1] >> 1);
|
|
128
|
+
key[2] = ((key56[1] << 6) & 0xFF) | (key56[2] >> 2);
|
|
129
|
+
key[3] = ((key56[2] << 5) & 0xFF) | (key56[3] >> 3);
|
|
130
|
+
key[4] = ((key56[3] << 4) & 0xFF) | (key56[4] >> 4);
|
|
131
|
+
key[5] = ((key56[4] << 3) & 0xFF) | (key56[5] >> 5);
|
|
132
|
+
key[6] = ((key56[5] << 2) & 0xFF) | (key56[6] >> 6);
|
|
133
|
+
key[7] = (key56[6] << 1) & 0xFF;
|
|
134
|
+
for (let i = 0; i < key.length; i++) { // Fix DES key parity bits.
|
|
135
|
+
let bit = 0;
|
|
136
|
+
for (let k = 0; k < 7; k++) {
|
|
137
|
+
const t = key[i] >> k;
|
|
138
|
+
bit = (t ^ bit) & 0x1;
|
|
139
|
+
}
|
|
140
|
+
key[i] = (key[i] & 0xFE) | bit;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
let result = '';
|
|
144
|
+
key.forEach((i) => {
|
|
145
|
+
result += String.fromCharCode(i);
|
|
146
|
+
});
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
buildResponse(key: string, text: string): string {
|
|
151
|
+
while (key.length < 21) {
|
|
152
|
+
key += '\0';
|
|
153
|
+
}
|
|
154
|
+
const key1 = this.createKey(key.substr(0, 7));
|
|
155
|
+
const key2 = this.createKey(key.substr(7, 7));
|
|
156
|
+
const key3 = this.createKey(key.substr(14, 7));
|
|
157
|
+
return Des.des(key1, text, 1, 0) +
|
|
158
|
+
Des.des(key2, text, 1, 0) +
|
|
159
|
+
Des.des(key3, text, 1, 0);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
// to be called by constructor
|
|
163
|
+
setCredentials(): void {
|
|
164
|
+
const domain = this.domain;
|
|
165
|
+
const password = this.passwd;
|
|
166
|
+
const magic = 'KGS!@#$%'; // Create LM password hash.
|
|
167
|
+
let lmPassword = password.toUpperCase().substr(0, 14);
|
|
168
|
+
while (lmPassword.length < 14) {
|
|
169
|
+
lmPassword += '\0';
|
|
170
|
+
}
|
|
171
|
+
const key1 = this.createKey(lmPassword);
|
|
172
|
+
const key2 = this.createKey(lmPassword.substr(7));
|
|
173
|
+
const lmHashedPassword = Des.des(key1, magic, 1, 0) +
|
|
174
|
+
Des.des(key2, magic, 1, 0);
|
|
175
|
+
|
|
176
|
+
let ntPassword = ''; // Create NT password hash.
|
|
177
|
+
for (let i = 0; i < password.length; i++) {
|
|
178
|
+
ntPassword += password.charAt(i) + '\0';
|
|
179
|
+
}
|
|
180
|
+
const ntHashedPassword = MD4.str(ntPassword);
|
|
181
|
+
|
|
182
|
+
this.domain = domain;
|
|
183
|
+
this.lmHashedPassword = lmHashedPassword;
|
|
184
|
+
this.ntHashedPassword = ntHashedPassword;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
export class NtlmMessage {
|
|
2
|
+
data:number[] = [];
|
|
3
|
+
|
|
4
|
+
constructor(data?: string) {
|
|
5
|
+
if (!data) {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
if (data.indexOf('NTLM ') === 0) {
|
|
9
|
+
data = data.substr(5);
|
|
10
|
+
}
|
|
11
|
+
atob(data).split('').map((c) => {
|
|
12
|
+
this.data.push(c.charCodeAt(0));
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
addByte(b: number): void {
|
|
17
|
+
this.data.push(b);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
addShort(s: number | string): void {
|
|
21
|
+
const typed = s as number;
|
|
22
|
+
this.data.push(typed & 0xFF);
|
|
23
|
+
this.data.push((typed >> 8) & 0xFF);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
addString(str: string, utf16?: boolean): void {
|
|
27
|
+
if (utf16) {
|
|
28
|
+
// Fake UTF16 by padding each character in string.
|
|
29
|
+
str = str.split('').map(function(c) {
|
|
30
|
+
return (c + '\0');
|
|
31
|
+
}).join('');
|
|
32
|
+
}
|
|
33
|
+
for (let i = 0; i < str.length; i++) {
|
|
34
|
+
this.data.push(str.charCodeAt(i));
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
getString(offset: number, length: number): string {
|
|
39
|
+
let result = '';
|
|
40
|
+
for (let i = 0; i < length; i++) {
|
|
41
|
+
if (offset + i >= this.data.length) {
|
|
42
|
+
return '';
|
|
43
|
+
}
|
|
44
|
+
result += String.fromCharCode(this.data[offset + i]);
|
|
45
|
+
}
|
|
46
|
+
return result;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
getByte(offset: number): number {
|
|
50
|
+
return this.data[offset];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
toBase64(): string {
|
|
54
|
+
const str = String.fromCharCode.apply(null, this.data);
|
|
55
|
+
return Buffer.from(str).toString('base64').replace(/.{76}(?=.)/g, '$&');
|
|
56
|
+
}
|
|
57
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { Headers } from '../../lib/headers/Headers.js';
|
|
2
|
+
import { IHttpRequest } from '../../models/HttpRequest.js';
|
|
3
|
+
import { INtlmAuthorization, IBasicAuthorization } from '../../models/Authorization.js';
|
|
4
|
+
import { ExecutionContext } from './ModulesRegistry.js';
|
|
5
|
+
import { IRequestAuthorization } from '../../models/RequestAuthorization.js';
|
|
6
|
+
|
|
7
|
+
const cache: any = {};
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Removes query parameters and the fragment part from the URL
|
|
11
|
+
* @param url The URL to process.
|
|
12
|
+
* @returns The canonical URL.
|
|
13
|
+
*/
|
|
14
|
+
export function computeUrlPath(url: string): string {
|
|
15
|
+
if (!url) {
|
|
16
|
+
return '';
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
const u = new URL(url);
|
|
20
|
+
u.hash = '';
|
|
21
|
+
u.search = '';
|
|
22
|
+
let result = u.toString();
|
|
23
|
+
// polyfill library has some error and leaves '?#' if was set
|
|
24
|
+
result = result.replace('?', '');
|
|
25
|
+
result = result.replace('#', '');
|
|
26
|
+
return result;
|
|
27
|
+
} catch (e) {
|
|
28
|
+
return url;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Finds an auth data for given `url`.
|
|
34
|
+
*
|
|
35
|
+
* @param type Authorization type.
|
|
36
|
+
* @param url The URL of the request.
|
|
37
|
+
* @return Auth data if exists in the cache.
|
|
38
|
+
*/
|
|
39
|
+
export function findCachedAuthData(type: string, url: string): IBasicAuthorization|INtlmAuthorization|undefined {
|
|
40
|
+
const key = computeUrlPath(url);
|
|
41
|
+
if (!cache || !type || !key || !cache[type]) {
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
return cache[type][key];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Updates cached authorization data
|
|
49
|
+
*
|
|
50
|
+
* @param type Authorization type.
|
|
51
|
+
* @param url The URL of the request.
|
|
52
|
+
* @param value Auth data to set
|
|
53
|
+
*/
|
|
54
|
+
export function updateCache(type: string, url: string, value: IBasicAuthorization|INtlmAuthorization): void {
|
|
55
|
+
const key = computeUrlPath(url);
|
|
56
|
+
if (!cache[type]) {
|
|
57
|
+
cache[type] = {};
|
|
58
|
+
}
|
|
59
|
+
cache[type][key] = value;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Applies the basic authorization data to the request.
|
|
64
|
+
*
|
|
65
|
+
* If the header value have changed then it fires `request-headers-changed` custom event.
|
|
66
|
+
* It sets computed value of the readers to the event's detail object.
|
|
67
|
+
*
|
|
68
|
+
* @param request The event's detail object. Changes made here will be propagated to the event.
|
|
69
|
+
* @param data The authorization data to apply.
|
|
70
|
+
*/
|
|
71
|
+
export function applyRequestBasicAuthData(request: IHttpRequest, data: IBasicAuthorization): void {
|
|
72
|
+
const { username='', password='' } = data;
|
|
73
|
+
const headers = new Headers(request.headers || '');
|
|
74
|
+
let hash: string;
|
|
75
|
+
let decoded = `${username}:${password}`;
|
|
76
|
+
if (typeof Buffer === 'function' && typeof Buffer.from === 'function') {
|
|
77
|
+
hash = Buffer.from(decoded).toString('base64');
|
|
78
|
+
} else {
|
|
79
|
+
hash = btoa(decoded);
|
|
80
|
+
}
|
|
81
|
+
headers.set('authorization', `Basic ${hash}`);
|
|
82
|
+
request.headers = headers.toString();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Applies the NTLM authorization data to the request.
|
|
87
|
+
*
|
|
88
|
+
* Because NTLM requires certain operations on a socket it's bot just about setting a headers
|
|
89
|
+
* but whole NTLM configuration object.
|
|
90
|
+
*
|
|
91
|
+
* Applied the `auth` object to the event's `detail.auth` object.
|
|
92
|
+
*
|
|
93
|
+
* @param {ArcBaseRequest} request The event's detail object. Changes made here will be propagated to
|
|
94
|
+
* the event.
|
|
95
|
+
* @param {NtlmAuthorization} values The authorization data to apply.
|
|
96
|
+
*/
|
|
97
|
+
function applyRequestNtlmAuthData(authorization: IRequestAuthorization[], values: INtlmAuthorization): void {
|
|
98
|
+
let ntlm: IRequestAuthorization | undefined = authorization.find(((method) => method.type === 'ntlm'));
|
|
99
|
+
if (!ntlm) {
|
|
100
|
+
ntlm = {
|
|
101
|
+
kind: '',
|
|
102
|
+
enabled: true,
|
|
103
|
+
type: 'ntlm',
|
|
104
|
+
config: {},
|
|
105
|
+
valid: true,
|
|
106
|
+
};
|
|
107
|
+
authorization.push(ntlm);
|
|
108
|
+
}
|
|
109
|
+
const cnf = ntlm.config as INtlmAuthorization;
|
|
110
|
+
if (cnf.username) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
cnf.username = values.username;
|
|
114
|
+
cnf.password = values.password;
|
|
115
|
+
cnf.domain = values.domain;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Adds basic authorization data to the request, when during this session basic auth was used
|
|
120
|
+
*/
|
|
121
|
+
export default function applyCachedBasicAuthData(request: IHttpRequest, context: ExecutionContext): void {
|
|
122
|
+
// Try to find an auth data for the URL. If has a match, apply it to the request
|
|
123
|
+
let authData = findCachedAuthData('basic', request.url);
|
|
124
|
+
if (authData) {
|
|
125
|
+
applyRequestBasicAuthData(request, authData);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
// Try NTLM
|
|
129
|
+
authData = findCachedAuthData('ntlm', request.url);
|
|
130
|
+
if (authData && Array.isArray(context.authorization)) {
|
|
131
|
+
applyRequestNtlmAuthData(context.authorization, authData as INtlmAuthorization);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { IHttpRequest } from '../../models/HttpRequest.js';
|
|
2
|
+
import { EnvironmentEvents } from '../../events/environment/EnvironmentEvents.js';
|
|
3
|
+
import { CookieEvents } from '../../events/cookies/CookieEvents.js';
|
|
4
|
+
import { EncryptionEvents } from '../../events/encryption/EncryptionEvents.js';
|
|
5
|
+
import { ProcessEvents } from '../../events/process/ProcessEvents.js';
|
|
6
|
+
import { AuthorizationEvents } from '../../events/authorization/AuthorizationEvents.js';
|
|
7
|
+
import { ClientCertificateEvents } from '../../events/models/ClientCertificateEvents.js';
|
|
8
|
+
import { IRequestAuthorization } from '../../models/RequestAuthorization.js';
|
|
9
|
+
import { IRequestConfig } from '../../models/RequestConfig.js';
|
|
10
|
+
import { IRequestLog } from '../../models/RequestLog.js';
|
|
11
|
+
import { IRequestCertificate } from '../../models/ClientCertificate.js';
|
|
12
|
+
|
|
13
|
+
export interface RegisteredRequestModule {
|
|
14
|
+
fn: (request: IHttpRequest, context: ExecutionContext) => Promise<number>;
|
|
15
|
+
permissions: RegistryPermission[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface RegisteredResponseModule {
|
|
19
|
+
fn: (log: IRequestLog, context: ExecutionContext) => Promise<number>;
|
|
20
|
+
permissions: RegistryPermission[];
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export enum RegistryPermission {
|
|
24
|
+
environment = 'environment',
|
|
25
|
+
events = 'events',
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface ExecutionContext {
|
|
29
|
+
/**
|
|
30
|
+
* The event target for events
|
|
31
|
+
*/
|
|
32
|
+
eventsTarget: EventTarget;
|
|
33
|
+
/**
|
|
34
|
+
* The events to use to communicate with the context store(s)
|
|
35
|
+
*/
|
|
36
|
+
Events?: ExecutionEvents;
|
|
37
|
+
/**
|
|
38
|
+
* The environment variables to use when executing the module.
|
|
39
|
+
*/
|
|
40
|
+
variables?: Record<string, string>;
|
|
41
|
+
/**
|
|
42
|
+
* Request authorization configuration
|
|
43
|
+
*/
|
|
44
|
+
authorization?: IRequestAuthorization[];
|
|
45
|
+
/**
|
|
46
|
+
* Optional request configuration.
|
|
47
|
+
*/
|
|
48
|
+
config?: IRequestConfig;
|
|
49
|
+
/**
|
|
50
|
+
* Can be altered by the actions.
|
|
51
|
+
*/
|
|
52
|
+
certificates?: IRequestCertificate[];
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface ExecutionEvents {
|
|
56
|
+
Authorization: typeof AuthorizationEvents;
|
|
57
|
+
Environment: typeof EnvironmentEvents;
|
|
58
|
+
Cookie: typeof CookieEvents;
|
|
59
|
+
Encryption: typeof EncryptionEvents;
|
|
60
|
+
Process: typeof ProcessEvents;
|
|
61
|
+
ClientCertificate: typeof ClientCertificateEvents;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The list of registered request processing modules.
|
|
66
|
+
*/
|
|
67
|
+
const requestModules = new Map<string, RegisteredRequestModule>();
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* The list of registered response processing modules.
|
|
71
|
+
*/
|
|
72
|
+
const responseModules = new Map<string, RegisteredResponseModule>();
|
|
73
|
+
|
|
74
|
+
export type RequestModule = 'request';
|
|
75
|
+
export type ResponseModule = 'response';
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* A registry for modules.
|
|
79
|
+
*/
|
|
80
|
+
export class ModulesRegistry {
|
|
81
|
+
static get request(): RequestModule { return 'request' }
|
|
82
|
+
|
|
83
|
+
static get response(): ResponseModule { return 'response' }
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Registers a new request or response module in the registry.
|
|
87
|
+
* @param context The name of the execution context
|
|
88
|
+
* @param id The identifier of the module
|
|
89
|
+
* @param fn The function to execute
|
|
90
|
+
* @param permissions The list of permissions for the module
|
|
91
|
+
* @throws {Error} When the module is already registered
|
|
92
|
+
*/
|
|
93
|
+
static register(context: ResponseModule|RequestModule, id: string, fn: Function, permissions?: string[]): void {
|
|
94
|
+
const data = {
|
|
95
|
+
fn,
|
|
96
|
+
permissions: Array.isArray(permissions) ? permissions : [],
|
|
97
|
+
};
|
|
98
|
+
const map = context === ModulesRegistry.request ? requestModules : responseModules;
|
|
99
|
+
if (map.has(id)) {
|
|
100
|
+
throw new Error(`Module ${id} already exists`);
|
|
101
|
+
}
|
|
102
|
+
// @ts-ignore
|
|
103
|
+
map.set(id, data);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Checks whether a module is already registered for the given context.
|
|
108
|
+
* @param {ModulesRegistry.request|ModulesRegistry.response} context The name of the execution context
|
|
109
|
+
* @param id The identifier of the module
|
|
110
|
+
*/
|
|
111
|
+
static has(context: ResponseModule|RequestModule, id: string): boolean {
|
|
112
|
+
const map = context === ModulesRegistry.request ? requestModules : responseModules;
|
|
113
|
+
return map.has(id);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Removes a registered module
|
|
118
|
+
* @param {ModulesRegistry.request|ModulesRegistry.response} context The name of the execution context
|
|
119
|
+
* @param {string} id The identifier of the module
|
|
120
|
+
*/
|
|
121
|
+
static unregister(context: ResponseModule|RequestModule, id: string): void {
|
|
122
|
+
const map = context === ModulesRegistry.request ? requestModules : responseModules;
|
|
123
|
+
map.delete(id);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Reads the list of registered modules
|
|
128
|
+
* @param context The name of the execution context
|
|
129
|
+
* @returns The copy of the map of actions.
|
|
130
|
+
*/
|
|
131
|
+
static get(context: ResponseModule|RequestModule): Map<string, RegisteredRequestModule|RegisteredResponseModule> {
|
|
132
|
+
const map = context === ModulesRegistry.request ? requestModules : responseModules;
|
|
133
|
+
// @ts-ignore
|
|
134
|
+
return new Map(map);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { Headers } from '../../lib/headers/Headers.js';
|
|
2
|
+
import { ExecutionResponse } from './ExecutionResponse.js';
|
|
3
|
+
import applyCachedBasicAuthData, { applyRequestBasicAuthData } from './BasicAuthCache.js';
|
|
4
|
+
import { IHttpRequest } from '../../models/HttpRequest.js';
|
|
5
|
+
import { IBearerAuthorization, IBasicAuthorization, IOidcAuthorization, IOAuth2Authorization, ICCAuthorization } from '../../models/Authorization.js';
|
|
6
|
+
import { ExecutionContext } from './ModulesRegistry.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Injects client certificate object into the request object
|
|
10
|
+
*/
|
|
11
|
+
async function processClientCertificate(config: ICCAuthorization, context: ExecutionContext): Promise<void> {
|
|
12
|
+
const { id } = config;
|
|
13
|
+
if (!id || !context.Events) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
const result = await context.Events.ClientCertificate.read(context.eventsTarget, id);
|
|
17
|
+
if (!result) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (!Array.isArray(context.certificates)) {
|
|
21
|
+
context.certificates = [];
|
|
22
|
+
}
|
|
23
|
+
context.certificates.push(result);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Injects basic auth header into the request headers.
|
|
28
|
+
*/
|
|
29
|
+
function processBasicAuth(request: IHttpRequest, config: IBasicAuthorization): void {
|
|
30
|
+
const { username } = config;
|
|
31
|
+
if (!username) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
applyRequestBasicAuthData(request, config);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Injects oauth 2 auth header into the request headers.
|
|
39
|
+
*/
|
|
40
|
+
function processOAuth2(request: IHttpRequest, config: IOAuth2Authorization): void {
|
|
41
|
+
const { accessToken, tokenType='Bearer', deliveryMethod='header', deliveryName='authorization' } = config;
|
|
42
|
+
if (!accessToken) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const value = `${tokenType} ${accessToken}`;
|
|
46
|
+
if (deliveryMethod === 'header') {
|
|
47
|
+
const headers = new Headers(request.headers || '');
|
|
48
|
+
headers.append(deliveryName, value);
|
|
49
|
+
request.headers = headers.toString();
|
|
50
|
+
} else if (deliveryMethod === 'query') {
|
|
51
|
+
const { url } = request;
|
|
52
|
+
try {
|
|
53
|
+
const parsed = new URL(url);
|
|
54
|
+
parsed.searchParams.append(deliveryName, value);
|
|
55
|
+
request.url = parsed.toString();
|
|
56
|
+
} catch (e) {
|
|
57
|
+
// ...
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Injects OpenID Connect auth header into the request headers.
|
|
64
|
+
*/
|
|
65
|
+
function processOpenId(request: IHttpRequest, config: IOidcAuthorization): void {
|
|
66
|
+
const { accessToken } = config;
|
|
67
|
+
if (accessToken) {
|
|
68
|
+
processOAuth2(request, config);
|
|
69
|
+
}
|
|
70
|
+
// todo - if AT is missing find the current token from the tokens list in the passed configuration.
|
|
71
|
+
// Currently the authorization method UI sets the token when the requests is generated so it's not as much important.
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Injects bearer auth header into the request headers.
|
|
76
|
+
*/
|
|
77
|
+
function processBearer(request: IHttpRequest, config: IBearerAuthorization): void {
|
|
78
|
+
const { token } = config;
|
|
79
|
+
const value = `Bearer ${token}`;
|
|
80
|
+
const headers = new Headers(request.headers || '');
|
|
81
|
+
headers.append('authorization', value);
|
|
82
|
+
request.headers = headers.toString();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Processes authorization data from the authorization configuration and injects data into the request object when necessary.
|
|
87
|
+
*/
|
|
88
|
+
export default async function processAuth(request: IHttpRequest, context: ExecutionContext): Promise<number> {
|
|
89
|
+
if (!Array.isArray(context.authorization) || !context.authorization.length) {
|
|
90
|
+
return ExecutionResponse.OK;
|
|
91
|
+
}
|
|
92
|
+
for (const auth of context.authorization) {
|
|
93
|
+
if (!auth.enabled || !auth.config) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
switch (auth.type) {
|
|
97
|
+
case 'client certificate': await processClientCertificate(auth.config as ICCAuthorization, context); break;
|
|
98
|
+
case 'basic': processBasicAuth(request, auth.config as IBasicAuthorization); break;
|
|
99
|
+
case 'oauth 2': processOAuth2(request, auth.config as IOAuth2Authorization); break;
|
|
100
|
+
case 'open id': processOpenId(request, auth.config as IOidcAuthorization); break;
|
|
101
|
+
case 'bearer': processBearer(request, auth.config as IBearerAuthorization); break;
|
|
102
|
+
default:
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (request.url && !/^authorization:\s?.+$/gim.test(request.headers || '')) {
|
|
106
|
+
// Try to apply basic auth from the cached during this session values.
|
|
107
|
+
applyCachedBasicAuthData(request, context);
|
|
108
|
+
}
|
|
109
|
+
return ExecutionResponse.OK;
|
|
110
|
+
}
|