@principal-ai/control-tower-core 0.1.21 → 0.1.23
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/abstractions/AuthAdapter.d.ts +1 -3
- package/dist/abstractions/AuthAdapter.d.ts.map +1 -1
- package/dist/adapters/mock/MockAuthAdapter.d.ts +12 -6
- package/dist/adapters/mock/MockAuthAdapter.d.ts.map +1 -1
- package/dist/adapters/mock/MockAuthAdapter.js +20 -114
- package/dist/adapters/websocket/WebSocketClientTransportAdapter.d.ts.map +1 -1
- package/dist/adapters/websocket/WebSocketClientTransportAdapter.js +9 -1
- package/dist/adapters/websocket/WebSocketServerTransportAdapter.d.ts.map +1 -1
- package/dist/adapters/websocket/WebSocketServerTransportAdapter.js +65 -114
- package/dist/client/BaseClient.d.ts +9 -3
- package/dist/client/BaseClient.d.ts.map +1 -1
- package/dist/client/BaseClient.js +24 -26
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +6 -6
- package/dist/index.mjs +96 -230
- package/dist/index.mjs.map +6 -6
- package/dist/types/auth.d.ts +0 -21
- package/dist/types/auth.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -3859,25 +3859,13 @@ class MockStorageAdapter {
|
|
|
3859
3859
|
class MockAuthAdapter {
|
|
3860
3860
|
tokens = new Map;
|
|
3861
3861
|
revokedTokens = new Set;
|
|
3862
|
-
users = new Map;
|
|
3863
3862
|
simulateLatency = 0;
|
|
3864
3863
|
shouldFailAuth = false;
|
|
3865
3864
|
tokenCounter = 0;
|
|
3865
|
+
currentToken = null;
|
|
3866
3866
|
constructor(options) {
|
|
3867
3867
|
this.simulateLatency = options?.simulateLatency ?? 0;
|
|
3868
3868
|
this.shouldFailAuth = options?.shouldFailAuth ?? false;
|
|
3869
|
-
this.addUser("testuser", "password123", {
|
|
3870
|
-
userId: "user-1",
|
|
3871
|
-
email: "test@example.com",
|
|
3872
|
-
username: "testuser",
|
|
3873
|
-
permissions: ["read", "write"]
|
|
3874
|
-
});
|
|
3875
|
-
this.addUser("admin", "admin123", {
|
|
3876
|
-
userId: "user-admin",
|
|
3877
|
-
email: "admin@example.com",
|
|
3878
|
-
username: "admin",
|
|
3879
|
-
permissions: ["read", "write", "admin"]
|
|
3880
|
-
});
|
|
3881
3869
|
}
|
|
3882
3870
|
async validateToken(token) {
|
|
3883
3871
|
await this.simulateDelay();
|
|
@@ -3928,94 +3916,8 @@ class MockAuthAdapter {
|
|
|
3928
3916
|
this.tokens.delete(token);
|
|
3929
3917
|
this.revokedTokens.add(token);
|
|
3930
3918
|
}
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
if (this.shouldFailAuth) {
|
|
3934
|
-
return {
|
|
3935
|
-
success: false,
|
|
3936
|
-
error: "Mock authentication failed"
|
|
3937
|
-
};
|
|
3938
|
-
}
|
|
3939
|
-
switch (credentials.type) {
|
|
3940
|
-
case "password": {
|
|
3941
|
-
if (!credentials.username || !credentials.password) {
|
|
3942
|
-
return {
|
|
3943
|
-
success: false,
|
|
3944
|
-
error: "Username and password required"
|
|
3945
|
-
};
|
|
3946
|
-
}
|
|
3947
|
-
const user = this.users.get(credentials.username);
|
|
3948
|
-
if (!user || user.password !== credentials.password) {
|
|
3949
|
-
return {
|
|
3950
|
-
success: false,
|
|
3951
|
-
error: "Invalid credentials"
|
|
3952
|
-
};
|
|
3953
|
-
}
|
|
3954
|
-
const token = await this.generateToken(user.payload);
|
|
3955
|
-
const refreshToken = `refresh-${token}`;
|
|
3956
|
-
this.tokens.set(refreshToken, user.payload);
|
|
3957
|
-
return {
|
|
3958
|
-
success: true,
|
|
3959
|
-
token,
|
|
3960
|
-
refreshToken,
|
|
3961
|
-
user: user.payload,
|
|
3962
|
-
userId: user.payload.userId,
|
|
3963
|
-
expiresIn: 3600
|
|
3964
|
-
};
|
|
3965
|
-
}
|
|
3966
|
-
case "token":
|
|
3967
|
-
case "jwt":
|
|
3968
|
-
case "bearer": {
|
|
3969
|
-
if (!credentials.token) {
|
|
3970
|
-
return {
|
|
3971
|
-
success: false,
|
|
3972
|
-
error: "Token required"
|
|
3973
|
-
};
|
|
3974
|
-
}
|
|
3975
|
-
try {
|
|
3976
|
-
const payload = await this.validateToken(credentials.token);
|
|
3977
|
-
return {
|
|
3978
|
-
success: true,
|
|
3979
|
-
token: credentials.token,
|
|
3980
|
-
user: payload,
|
|
3981
|
-
userId: payload.userId,
|
|
3982
|
-
expiresIn: 3600
|
|
3983
|
-
};
|
|
3984
|
-
} catch (error) {
|
|
3985
|
-
return {
|
|
3986
|
-
success: false,
|
|
3987
|
-
error: error.message
|
|
3988
|
-
};
|
|
3989
|
-
}
|
|
3990
|
-
}
|
|
3991
|
-
case "oauth": {
|
|
3992
|
-
if (!credentials.code) {
|
|
3993
|
-
return {
|
|
3994
|
-
success: false,
|
|
3995
|
-
error: "OAuth code required"
|
|
3996
|
-
};
|
|
3997
|
-
}
|
|
3998
|
-
const payload = {
|
|
3999
|
-
userId: `oauth-user-${Date.now()}`,
|
|
4000
|
-
email: "oauth@example.com",
|
|
4001
|
-
username: "oauthuser",
|
|
4002
|
-
permissions: ["read", "write"]
|
|
4003
|
-
};
|
|
4004
|
-
const token = await this.generateToken(payload);
|
|
4005
|
-
return {
|
|
4006
|
-
success: true,
|
|
4007
|
-
token,
|
|
4008
|
-
user: payload,
|
|
4009
|
-
userId: payload.userId,
|
|
4010
|
-
expiresIn: 3600
|
|
4011
|
-
};
|
|
4012
|
-
}
|
|
4013
|
-
default:
|
|
4014
|
-
return {
|
|
4015
|
-
success: false,
|
|
4016
|
-
error: "Unsupported credential type"
|
|
4017
|
-
};
|
|
4018
|
-
}
|
|
3919
|
+
getCurrentToken() {
|
|
3920
|
+
return this.currentToken;
|
|
4019
3921
|
}
|
|
4020
3922
|
isAuthRequired() {
|
|
4021
3923
|
return false;
|
|
@@ -4023,19 +3925,21 @@ class MockAuthAdapter {
|
|
|
4023
3925
|
getAuthTimeout() {
|
|
4024
3926
|
return 1e4;
|
|
4025
3927
|
}
|
|
4026
|
-
getSupportedCredentialTypes() {
|
|
4027
|
-
return ["password", "token", "jwt", "bearer", "oauth"];
|
|
4028
|
-
}
|
|
4029
3928
|
async simulateDelay() {
|
|
4030
3929
|
if (this.simulateLatency > 0) {
|
|
4031
3930
|
await new Promise((resolve) => setTimeout(resolve, this.simulateLatency));
|
|
4032
3931
|
}
|
|
4033
3932
|
}
|
|
4034
|
-
|
|
4035
|
-
|
|
4036
|
-
|
|
4037
|
-
|
|
4038
|
-
|
|
3933
|
+
async createTestToken(userId, options) {
|
|
3934
|
+
const payload = {
|
|
3935
|
+
userId,
|
|
3936
|
+
permissions: options?.permissions ?? ["read", "write"],
|
|
3937
|
+
metadata: options?.metadata,
|
|
3938
|
+
expiresAt: options?.expiresIn ? Date.now() + options.expiresIn : undefined
|
|
3939
|
+
};
|
|
3940
|
+
const token = await this.generateToken(payload);
|
|
3941
|
+
this.currentToken = token;
|
|
3942
|
+
return token;
|
|
4039
3943
|
}
|
|
4040
3944
|
getTokenCount() {
|
|
4041
3945
|
return this.tokens.size;
|
|
@@ -4046,10 +3950,14 @@ class MockAuthAdapter {
|
|
|
4046
3950
|
clearTokens() {
|
|
4047
3951
|
this.tokens.clear();
|
|
4048
3952
|
this.revokedTokens.clear();
|
|
3953
|
+
this.currentToken = null;
|
|
4049
3954
|
}
|
|
4050
3955
|
setFailAuth(fail) {
|
|
4051
3956
|
this.shouldFailAuth = fail;
|
|
4052
3957
|
}
|
|
3958
|
+
setCurrentToken(token) {
|
|
3959
|
+
this.currentToken = token;
|
|
3960
|
+
}
|
|
4053
3961
|
}
|
|
4054
3962
|
// node_modules/ws/wrapper.mjs
|
|
4055
3963
|
var import_stream = __toESM(require_stream(), 1);
|
|
@@ -4167,16 +4075,16 @@ class WebSocketServerTransportAdapter {
|
|
|
4167
4075
|
async handleConnection(ws, req) {
|
|
4168
4076
|
const clientId = this.generateId();
|
|
4169
4077
|
let authenticated = false;
|
|
4170
|
-
let
|
|
4078
|
+
let userId;
|
|
4079
|
+
let metadata;
|
|
4171
4080
|
if (this.authAdapter && req.headers.authorization) {
|
|
4172
4081
|
const token = this.extractBearerToken(req.headers.authorization);
|
|
4173
4082
|
if (token) {
|
|
4174
4083
|
try {
|
|
4175
|
-
|
|
4176
|
-
|
|
4177
|
-
|
|
4178
|
-
|
|
4179
|
-
authenticated = authResult.success;
|
|
4084
|
+
const tokenPayload = await this.authAdapter.validateToken(token);
|
|
4085
|
+
authenticated = true;
|
|
4086
|
+
userId = tokenPayload.userId;
|
|
4087
|
+
metadata = tokenPayload.metadata;
|
|
4180
4088
|
} catch {}
|
|
4181
4089
|
}
|
|
4182
4090
|
}
|
|
@@ -4184,8 +4092,8 @@ class WebSocketServerTransportAdapter {
|
|
|
4184
4092
|
id: clientId,
|
|
4185
4093
|
ws,
|
|
4186
4094
|
authenticated,
|
|
4187
|
-
userId
|
|
4188
|
-
metadata
|
|
4095
|
+
userId,
|
|
4096
|
+
metadata,
|
|
4189
4097
|
connectedAt: Date.now()
|
|
4190
4098
|
};
|
|
4191
4099
|
this.clients.set(clientId, client);
|
|
@@ -4257,107 +4165,65 @@ class WebSocketServerTransportAdapter {
|
|
|
4257
4165
|
if (!this.authAdapter) {
|
|
4258
4166
|
this.sendToClient(client, {
|
|
4259
4167
|
id: this.generateId(),
|
|
4260
|
-
type: "
|
|
4261
|
-
payload: { error: "No auth adapter configured" },
|
|
4168
|
+
type: "auth_result",
|
|
4169
|
+
payload: { success: false, error: "No auth adapter configured" },
|
|
4170
|
+
timestamp: Date.now()
|
|
4171
|
+
});
|
|
4172
|
+
return;
|
|
4173
|
+
}
|
|
4174
|
+
const payload = message.payload;
|
|
4175
|
+
if (!payload.token || typeof payload.token !== "string") {
|
|
4176
|
+
this.sendToClient(client, {
|
|
4177
|
+
id: this.generateId(),
|
|
4178
|
+
type: "auth_result",
|
|
4179
|
+
payload: { success: false, error: "Token required for authentication" },
|
|
4262
4180
|
timestamp: Date.now()
|
|
4263
4181
|
});
|
|
4264
4182
|
return;
|
|
4265
4183
|
}
|
|
4266
4184
|
try {
|
|
4267
|
-
const
|
|
4268
|
-
if (
|
|
4269
|
-
|
|
4270
|
-
|
|
4271
|
-
if (client.authTimeout) {
|
|
4272
|
-
clearTimeout(client.authTimeout);
|
|
4273
|
-
client.authTimeout = undefined;
|
|
4274
|
-
}
|
|
4275
|
-
client.authenticated = true;
|
|
4276
|
-
client.userId = tokenPayload.userId;
|
|
4277
|
-
client.metadata = tokenPayload.metadata;
|
|
4278
|
-
this.sendToClient(client, {
|
|
4279
|
-
id: this.generateId(),
|
|
4280
|
-
type: "auth_result",
|
|
4281
|
-
payload: {
|
|
4282
|
-
success: true,
|
|
4283
|
-
userId: client.userId
|
|
4284
|
-
},
|
|
4285
|
-
timestamp: Date.now()
|
|
4286
|
-
});
|
|
4287
|
-
const authMessage = {
|
|
4288
|
-
id: this.generateId(),
|
|
4289
|
-
type: "client_authenticated",
|
|
4290
|
-
payload: {
|
|
4291
|
-
clientId: client.id,
|
|
4292
|
-
userId: client.userId,
|
|
4293
|
-
metadata: client.metadata
|
|
4294
|
-
},
|
|
4295
|
-
timestamp: Date.now()
|
|
4296
|
-
};
|
|
4297
|
-
this.messageHandlers.forEach((handler) => handler(authMessage));
|
|
4298
|
-
return;
|
|
4299
|
-
} catch (error) {
|
|
4300
|
-
this.sendToClient(client, {
|
|
4301
|
-
id: this.generateId(),
|
|
4302
|
-
type: "auth_result",
|
|
4303
|
-
payload: {
|
|
4304
|
-
success: false,
|
|
4305
|
-
error: error.message
|
|
4306
|
-
},
|
|
4307
|
-
timestamp: Date.now()
|
|
4308
|
-
});
|
|
4309
|
-
return;
|
|
4310
|
-
}
|
|
4311
|
-
}
|
|
4312
|
-
const credentials = payload;
|
|
4313
|
-
const result = await this.authAdapter.authenticate(credentials);
|
|
4314
|
-
if (result.success) {
|
|
4315
|
-
if (client.authTimeout) {
|
|
4316
|
-
clearTimeout(client.authTimeout);
|
|
4317
|
-
client.authTimeout = undefined;
|
|
4318
|
-
}
|
|
4319
|
-
client.authenticated = true;
|
|
4320
|
-
client.userId = result.userId || result.user?.userId;
|
|
4321
|
-
client.metadata = result.metadata || result.user?.metadata;
|
|
4322
|
-
this.sendToClient(client, {
|
|
4323
|
-
id: this.generateId(),
|
|
4324
|
-
type: "auth_success",
|
|
4325
|
-
payload: {
|
|
4326
|
-
userId: client.userId,
|
|
4327
|
-
metadata: client.metadata
|
|
4328
|
-
},
|
|
4329
|
-
timestamp: Date.now()
|
|
4330
|
-
});
|
|
4331
|
-
const authMessage = {
|
|
4332
|
-
id: this.generateId(),
|
|
4333
|
-
type: "client_authenticated",
|
|
4334
|
-
payload: {
|
|
4335
|
-
clientId: client.id,
|
|
4336
|
-
userId: client.userId,
|
|
4337
|
-
metadata: client.metadata
|
|
4338
|
-
},
|
|
4339
|
-
timestamp: Date.now()
|
|
4340
|
-
};
|
|
4341
|
-
this.messageHandlers.forEach((handler) => handler(authMessage));
|
|
4342
|
-
} else {
|
|
4343
|
-
this.sendToClient(client, {
|
|
4344
|
-
id: this.generateId(),
|
|
4345
|
-
type: "auth_error",
|
|
4346
|
-
payload: { error: result.error || "Authentication failed" },
|
|
4347
|
-
timestamp: Date.now()
|
|
4348
|
-
});
|
|
4349
|
-
if (this.config.closeOnAuthFailure) {
|
|
4350
|
-
client.ws.close(1008, "Authentication failed");
|
|
4351
|
-
this.clients.delete(client.id);
|
|
4352
|
-
}
|
|
4185
|
+
const tokenPayload = await this.authAdapter.validateToken(payload.token);
|
|
4186
|
+
if (client.authTimeout) {
|
|
4187
|
+
clearTimeout(client.authTimeout);
|
|
4188
|
+
client.authTimeout = undefined;
|
|
4353
4189
|
}
|
|
4190
|
+
client.authenticated = true;
|
|
4191
|
+
client.userId = tokenPayload.userId;
|
|
4192
|
+
client.metadata = tokenPayload.metadata;
|
|
4193
|
+
this.sendToClient(client, {
|
|
4194
|
+
id: this.generateId(),
|
|
4195
|
+
type: "auth_result",
|
|
4196
|
+
payload: {
|
|
4197
|
+
success: true,
|
|
4198
|
+
userId: client.userId
|
|
4199
|
+
},
|
|
4200
|
+
timestamp: Date.now()
|
|
4201
|
+
});
|
|
4202
|
+
const authMessage = {
|
|
4203
|
+
id: this.generateId(),
|
|
4204
|
+
type: "client_authenticated",
|
|
4205
|
+
payload: {
|
|
4206
|
+
clientId: client.id,
|
|
4207
|
+
userId: client.userId,
|
|
4208
|
+
metadata: client.metadata
|
|
4209
|
+
},
|
|
4210
|
+
timestamp: Date.now()
|
|
4211
|
+
};
|
|
4212
|
+
this.messageHandlers.forEach((handler) => handler(authMessage));
|
|
4354
4213
|
} catch (error) {
|
|
4355
4214
|
this.sendToClient(client, {
|
|
4356
4215
|
id: this.generateId(),
|
|
4357
|
-
type: "
|
|
4358
|
-
payload: {
|
|
4216
|
+
type: "auth_result",
|
|
4217
|
+
payload: {
|
|
4218
|
+
success: false,
|
|
4219
|
+
error: error.message
|
|
4220
|
+
},
|
|
4359
4221
|
timestamp: Date.now()
|
|
4360
4222
|
});
|
|
4223
|
+
if (this.config.closeOnAuthFailure) {
|
|
4224
|
+
client.ws.close(1008, "Authentication failed");
|
|
4225
|
+
this.clients.delete(client.id);
|
|
4226
|
+
}
|
|
4361
4227
|
}
|
|
4362
4228
|
}
|
|
4363
4229
|
extractBearerToken(authHeader) {
|
|
@@ -4628,7 +4494,13 @@ class WebSocketClientTransportAdapter {
|
|
|
4628
4494
|
}
|
|
4629
4495
|
this.heartbeatTimer = setInterval(() => {
|
|
4630
4496
|
if (this.ws && this.ws.readyState === import_websocket.default.OPEN) {
|
|
4631
|
-
|
|
4497
|
+
const heartbeatMessage = {
|
|
4498
|
+
id: `heartbeat-${Date.now()}`,
|
|
4499
|
+
type: "heartbeat",
|
|
4500
|
+
payload: { timestamp: Date.now() },
|
|
4501
|
+
timestamp: Date.now()
|
|
4502
|
+
};
|
|
4503
|
+
this.ws.send(JSON.stringify(heartbeatMessage));
|
|
4632
4504
|
}
|
|
4633
4505
|
}, this.config.heartbeatInterval);
|
|
4634
4506
|
}
|
|
@@ -4653,7 +4525,7 @@ class BaseClient extends TypedEventEmitter {
|
|
|
4653
4525
|
reconnectAttempts = 0;
|
|
4654
4526
|
reconnectTimer = null;
|
|
4655
4527
|
lastConnectionUrl = null;
|
|
4656
|
-
|
|
4528
|
+
lastToken = null;
|
|
4657
4529
|
constructor(config) {
|
|
4658
4530
|
super();
|
|
4659
4531
|
this.config = config;
|
|
@@ -4664,35 +4536,29 @@ class BaseClient extends TypedEventEmitter {
|
|
|
4664
4536
|
this.transport.onError(this.handleError.bind(this));
|
|
4665
4537
|
this.transport.onClose(this.handleClose.bind(this));
|
|
4666
4538
|
}
|
|
4667
|
-
async connect(url,
|
|
4539
|
+
async connect(url, token) {
|
|
4668
4540
|
if (this.connectionState !== "disconnected") {
|
|
4669
4541
|
throw new Error("Client is already connected or connecting");
|
|
4670
4542
|
}
|
|
4671
4543
|
this.connectionState = "connecting";
|
|
4672
4544
|
this.lastConnectionUrl = url;
|
|
4673
|
-
this.
|
|
4545
|
+
this.lastToken = token || null;
|
|
4674
4546
|
try {
|
|
4675
|
-
let tokenToApply = null;
|
|
4676
|
-
if (
|
|
4677
|
-
|
|
4678
|
-
|
|
4679
|
-
|
|
4680
|
-
|
|
4681
|
-
|
|
4682
|
-
}
|
|
4683
|
-
} else if (this.auth && typeof this.auth.getCurrentToken === "function") {
|
|
4684
|
-
const currentToken = this.auth.getCurrentToken();
|
|
4685
|
-
if (currentToken) {
|
|
4686
|
-
this.authToken = currentToken;
|
|
4687
|
-
tokenToApply = currentToken;
|
|
4547
|
+
let tokenToApply = token || null;
|
|
4548
|
+
if (!tokenToApply && this.auth && typeof this.auth.getCurrentToken === "function") {
|
|
4549
|
+
tokenToApply = this.auth.getCurrentToken();
|
|
4550
|
+
}
|
|
4551
|
+
if (tokenToApply) {
|
|
4552
|
+
this.authToken = tokenToApply;
|
|
4553
|
+
if (this.auth) {
|
|
4688
4554
|
try {
|
|
4689
|
-
const payload = await this.auth.validateToken(
|
|
4555
|
+
const payload = await this.auth.validateToken(tokenToApply);
|
|
4690
4556
|
this.userId = payload.userId;
|
|
4691
4557
|
} catch {}
|
|
4692
4558
|
}
|
|
4693
|
-
|
|
4694
|
-
|
|
4695
|
-
|
|
4559
|
+
if (typeof this.transport.setAuthToken === "function") {
|
|
4560
|
+
this.transport.setAuthToken(tokenToApply);
|
|
4561
|
+
}
|
|
4696
4562
|
}
|
|
4697
4563
|
const options = {
|
|
4698
4564
|
url,
|
|
@@ -4739,7 +4605,7 @@ class BaseClient extends TypedEventEmitter {
|
|
|
4739
4605
|
if (this.connectionState !== "disconnected") {
|
|
4740
4606
|
await this.disconnect();
|
|
4741
4607
|
}
|
|
4742
|
-
await this.connect(this.lastConnectionUrl, this.
|
|
4608
|
+
await this.connect(this.lastConnectionUrl, this.lastToken || undefined);
|
|
4743
4609
|
}
|
|
4744
4610
|
async authenticate(options) {
|
|
4745
4611
|
if (this.connectionState !== "connected") {
|
|
@@ -6021,4 +5887,4 @@ export {
|
|
|
6021
5887
|
BaseClient
|
|
6022
5888
|
};
|
|
6023
5889
|
|
|
6024
|
-
//# debugId=
|
|
5890
|
+
//# debugId=8CDBD5A49BC1736564756E2164756E21
|