@dishantlangayan/sc-cli-core 0.5.3 → 0.6.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/lib/auth/auth-encryption.d.ts +6 -5
- package/lib/auth/auth-encryption.js +14 -8
- package/lib/auth/auth-types.d.ts +0 -70
- package/lib/auth/auth-types.js +1 -41
- package/lib/auth/{auth-manager.d.ts → broker-auth-manager.d.ts} +1 -1
- package/lib/auth/{auth-manager.js → broker-auth-manager.js} +15 -21
- package/lib/auth/broker-auth-types.d.ts +56 -0
- package/lib/auth/broker-auth-types.js +40 -0
- package/lib/auth/index.d.ts +4 -3
- package/lib/auth/index.js +3 -3
- package/lib/auth/org-manager.js +8 -8
- package/lib/exported.d.ts +1 -1
- package/lib/sc-command.d.ts +1 -1
- package/lib/sc-command.js +1 -1
- package/package.json +1 -1
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import type { EncryptedData } from './auth-types.js';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Generic encryption utility for authentication storage
|
|
4
4
|
* Uses AES-256-GCM for authenticated encryption
|
|
5
|
+
* Can be used by both OrgManager and BrokerAuthManager
|
|
5
6
|
*/
|
|
6
|
-
export declare class
|
|
7
|
+
export declare class AuthEncryption {
|
|
7
8
|
private static readonly ALGORITHM;
|
|
8
9
|
private static readonly DIGEST;
|
|
9
10
|
private static readonly ITERATIONS;
|
|
@@ -17,7 +18,7 @@ export declare class BrokerAuthEncryption {
|
|
|
17
18
|
* @param key - Decryption key
|
|
18
19
|
* @returns Decrypted storage
|
|
19
20
|
*/
|
|
20
|
-
static decrypt<T
|
|
21
|
+
static decrypt<T>(encryptedData: EncryptedData, key: Buffer): Promise<T>;
|
|
21
22
|
/**
|
|
22
23
|
* Derive encryption key from password using PBKDF2
|
|
23
24
|
* @param password - User password
|
|
@@ -31,7 +32,7 @@ export declare class BrokerAuthEncryption {
|
|
|
31
32
|
* @param key - Encryption key
|
|
32
33
|
* @returns Encrypted data with metadata
|
|
33
34
|
*/
|
|
34
|
-
static encrypt<T
|
|
35
|
+
static encrypt<T>(data: T, key: Buffer): Promise<EncryptedData>;
|
|
35
36
|
/**
|
|
36
37
|
* Generate cryptographically secure random salt
|
|
37
38
|
* @returns Random salt buffer
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { createCipheriv, createDecipheriv, pbkdf2, randomBytes } from 'node:crypto';
|
|
2
2
|
import { promisify } from 'node:util';
|
|
3
|
-
import { BrokerAuthError, BrokerAuthErrorCode } from './auth-types.js';
|
|
4
3
|
const pbkdf2Async = promisify(pbkdf2);
|
|
5
4
|
/**
|
|
6
|
-
*
|
|
5
|
+
* Generic encryption utility for authentication storage
|
|
7
6
|
* Uses AES-256-GCM for authenticated encryption
|
|
7
|
+
* Can be used by both OrgManager and BrokerAuthManager
|
|
8
8
|
*/
|
|
9
|
-
export class
|
|
9
|
+
export class AuthEncryption {
|
|
10
10
|
static ALGORITHM = 'aes-256-gcm';
|
|
11
11
|
static DIGEST = 'sha256';
|
|
12
12
|
static ITERATIONS = 100_000; // OWASP recommended minimum for PBKDF2
|
|
@@ -36,7 +36,9 @@ export class BrokerAuthEncryption {
|
|
|
36
36
|
return storage;
|
|
37
37
|
}
|
|
38
38
|
catch (error) {
|
|
39
|
-
|
|
39
|
+
const err = new Error('Failed to decrypt storage. The password may be incorrect or the file may be corrupted.');
|
|
40
|
+
err.cause = error;
|
|
41
|
+
throw err;
|
|
40
42
|
}
|
|
41
43
|
}
|
|
42
44
|
/**
|
|
@@ -48,15 +50,17 @@ export class BrokerAuthEncryption {
|
|
|
48
50
|
static async deriveKey(password, salt) {
|
|
49
51
|
try {
|
|
50
52
|
if (!password || password.length === 0) {
|
|
51
|
-
throw new
|
|
53
|
+
throw new Error('Password cannot be empty');
|
|
52
54
|
}
|
|
53
55
|
return await pbkdf2Async(password, salt, this.ITERATIONS, this.KEY_LENGTH, this.DIGEST);
|
|
54
56
|
}
|
|
55
57
|
catch (error) {
|
|
56
|
-
if (error instanceof
|
|
58
|
+
if (error instanceof Error && error.message === 'Password cannot be empty') {
|
|
57
59
|
throw error;
|
|
58
60
|
}
|
|
59
|
-
|
|
61
|
+
const err = new Error('Failed to derive encryption key');
|
|
62
|
+
err.cause = error;
|
|
63
|
+
throw err;
|
|
60
64
|
}
|
|
61
65
|
}
|
|
62
66
|
/**
|
|
@@ -93,7 +97,9 @@ export class BrokerAuthEncryption {
|
|
|
93
97
|
};
|
|
94
98
|
}
|
|
95
99
|
catch (error) {
|
|
96
|
-
|
|
100
|
+
const err = new Error('Failed to encrypt storage');
|
|
101
|
+
err.cause = error;
|
|
102
|
+
throw err;
|
|
97
103
|
}
|
|
98
104
|
}
|
|
99
105
|
/**
|
package/lib/auth/auth-types.d.ts
CHANGED
|
@@ -1,46 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Authentication types supported by the broker auth system
|
|
3
|
-
*/
|
|
4
|
-
export declare enum AuthType {
|
|
5
|
-
BASIC = "basic",
|
|
6
|
-
OAUTH = "oauth"
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Base broker authentication configuration
|
|
10
|
-
*/
|
|
11
|
-
export interface BrokerAuthBase {
|
|
12
|
-
authType: AuthType;
|
|
13
|
-
name: string;
|
|
14
|
-
sempEndpoint: string;
|
|
15
|
-
sempPort: number;
|
|
16
|
-
}
|
|
17
|
-
/**
|
|
18
|
-
* OAuth broker authentication configuration
|
|
19
|
-
*/
|
|
20
|
-
export interface OAuthBrokerAuth extends BrokerAuthBase {
|
|
21
|
-
accessToken: string;
|
|
22
|
-
authType: AuthType.OAUTH;
|
|
23
|
-
clientId: string;
|
|
24
|
-
refreshToken: string;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Basic authentication broker configuration
|
|
28
|
-
*/
|
|
29
|
-
export interface BasicBrokerAuth extends BrokerAuthBase {
|
|
30
|
-
authType: AuthType.BASIC;
|
|
31
|
-
encodedCredentials: string;
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Union type for broker authentication
|
|
35
|
-
*/
|
|
36
|
-
export type BrokerAuth = BasicBrokerAuth | OAuthBrokerAuth;
|
|
37
|
-
/**
|
|
38
|
-
* Storage format for broker configurations
|
|
39
|
-
*/
|
|
40
|
-
export interface BrokerAuthStorage {
|
|
41
|
-
brokers: BrokerAuth[];
|
|
42
|
-
version: string;
|
|
43
|
-
}
|
|
44
1
|
/**
|
|
45
2
|
* Encryption metadata stored alongside encrypted data
|
|
46
3
|
*/
|
|
@@ -60,30 +17,3 @@ export interface EncryptedData {
|
|
|
60
17
|
metadata: EncryptionMetadata;
|
|
61
18
|
salt: string;
|
|
62
19
|
}
|
|
63
|
-
/**
|
|
64
|
-
* Error codes for broker auth operations
|
|
65
|
-
*/
|
|
66
|
-
export declare enum BrokerAuthErrorCode {
|
|
67
|
-
BROKER_ALREADY_EXISTS = "BROKER_ALREADY_EXISTS",
|
|
68
|
-
BROKER_NOT_FOUND = "BROKER_NOT_FOUND",
|
|
69
|
-
DECRYPTION_FAILED = "DECRYPTION_FAILED",
|
|
70
|
-
ENCRYPTION_FAILED = "ENCRYPTION_FAILED",
|
|
71
|
-
FILE_READ_ERROR = "FILE_READ_ERROR",
|
|
72
|
-
FILE_WRITE_ERROR = "FILE_WRITE_ERROR",
|
|
73
|
-
INVALID_AUTH_TYPE = "INVALID_AUTH_TYPE",
|
|
74
|
-
INVALID_BASIC_CONFIG = "INVALID_BASIC_CONFIG",
|
|
75
|
-
INVALID_ENDPOINT = "INVALID_ENDPOINT",
|
|
76
|
-
INVALID_NAME = "INVALID_NAME",
|
|
77
|
-
INVALID_OAUTH_CONFIG = "INVALID_OAUTH_CONFIG",
|
|
78
|
-
INVALID_PASSWORD = "INVALID_PASSWORD",
|
|
79
|
-
INVALID_PORT = "INVALID_PORT",
|
|
80
|
-
NOT_INITIALIZED = "NOT_INITIALIZED"
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Custom error class for broker authentication operations
|
|
84
|
-
*/
|
|
85
|
-
export declare class BrokerAuthError extends Error {
|
|
86
|
-
readonly code: BrokerAuthErrorCode;
|
|
87
|
-
readonly cause?: Error | undefined;
|
|
88
|
-
constructor(message: string, code: BrokerAuthErrorCode, cause?: Error | undefined);
|
|
89
|
-
}
|
package/lib/auth/auth-types.js
CHANGED
|
@@ -1,41 +1 @@
|
|
|
1
|
-
|
|
2
|
-
* Authentication types supported by the broker auth system
|
|
3
|
-
*/
|
|
4
|
-
export var AuthType;
|
|
5
|
-
(function (AuthType) {
|
|
6
|
-
AuthType["BASIC"] = "basic";
|
|
7
|
-
AuthType["OAUTH"] = "oauth";
|
|
8
|
-
})(AuthType || (AuthType = {}));
|
|
9
|
-
/**
|
|
10
|
-
* Error codes for broker auth operations
|
|
11
|
-
*/
|
|
12
|
-
export var BrokerAuthErrorCode;
|
|
13
|
-
(function (BrokerAuthErrorCode) {
|
|
14
|
-
BrokerAuthErrorCode["BROKER_ALREADY_EXISTS"] = "BROKER_ALREADY_EXISTS";
|
|
15
|
-
BrokerAuthErrorCode["BROKER_NOT_FOUND"] = "BROKER_NOT_FOUND";
|
|
16
|
-
BrokerAuthErrorCode["DECRYPTION_FAILED"] = "DECRYPTION_FAILED";
|
|
17
|
-
BrokerAuthErrorCode["ENCRYPTION_FAILED"] = "ENCRYPTION_FAILED";
|
|
18
|
-
BrokerAuthErrorCode["FILE_READ_ERROR"] = "FILE_READ_ERROR";
|
|
19
|
-
BrokerAuthErrorCode["FILE_WRITE_ERROR"] = "FILE_WRITE_ERROR";
|
|
20
|
-
BrokerAuthErrorCode["INVALID_AUTH_TYPE"] = "INVALID_AUTH_TYPE";
|
|
21
|
-
BrokerAuthErrorCode["INVALID_BASIC_CONFIG"] = "INVALID_BASIC_CONFIG";
|
|
22
|
-
BrokerAuthErrorCode["INVALID_ENDPOINT"] = "INVALID_ENDPOINT";
|
|
23
|
-
BrokerAuthErrorCode["INVALID_NAME"] = "INVALID_NAME";
|
|
24
|
-
BrokerAuthErrorCode["INVALID_OAUTH_CONFIG"] = "INVALID_OAUTH_CONFIG";
|
|
25
|
-
BrokerAuthErrorCode["INVALID_PASSWORD"] = "INVALID_PASSWORD";
|
|
26
|
-
BrokerAuthErrorCode["INVALID_PORT"] = "INVALID_PORT";
|
|
27
|
-
BrokerAuthErrorCode["NOT_INITIALIZED"] = "NOT_INITIALIZED";
|
|
28
|
-
})(BrokerAuthErrorCode || (BrokerAuthErrorCode = {}));
|
|
29
|
-
/**
|
|
30
|
-
* Custom error class for broker authentication operations
|
|
31
|
-
*/
|
|
32
|
-
export class BrokerAuthError extends Error {
|
|
33
|
-
code;
|
|
34
|
-
cause;
|
|
35
|
-
constructor(message, code, cause) {
|
|
36
|
-
super(message);
|
|
37
|
-
this.code = code;
|
|
38
|
-
this.cause = cause;
|
|
39
|
-
this.name = 'BrokerAuthError';
|
|
40
|
-
}
|
|
41
|
-
}
|
|
1
|
+
export {};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ScConnection } from '../util/sc-connection.js';
|
|
2
|
-
import { type BrokerAuth } from './auth-types.js';
|
|
2
|
+
import { type BrokerAuth } from './broker-auth-types.js';
|
|
3
3
|
import { KeychainService } from './keychain.js';
|
|
4
4
|
/**
|
|
5
5
|
* Manager for broker authentication storage
|
|
@@ -2,8 +2,8 @@ import { mkdir, readFile, rename, unlink, writeFile } from 'node:fs/promises';
|
|
|
2
2
|
import { homedir } from 'node:os';
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { ScConnection } from '../util/sc-connection.js';
|
|
5
|
-
import {
|
|
6
|
-
import { AuthType, BrokerAuthError, BrokerAuthErrorCode, } from './auth-types.js';
|
|
5
|
+
import { AuthEncryption } from './auth-encryption.js';
|
|
6
|
+
import { AuthType, BrokerAuthError, BrokerAuthErrorCode, } from './broker-auth-types.js';
|
|
7
7
|
import { KeychainService } from './keychain.js';
|
|
8
8
|
const SERVICE_NAME = 'local';
|
|
9
9
|
const KEY_NAME = 'sc-cli';
|
|
@@ -84,7 +84,7 @@ export class BrokerAuthManager {
|
|
|
84
84
|
throw new BrokerAuthError(`Broker '${brokerName}' not found`, BrokerAuthErrorCode.BROKER_NOT_FOUND);
|
|
85
85
|
}
|
|
86
86
|
const baseURL = `${broker.sempEndpoint}:${broker.sempPort}`;
|
|
87
|
-
const accessToken = broker.
|
|
87
|
+
const accessToken = broker.accessToken;
|
|
88
88
|
return new ScConnection(baseURL, accessToken, {
|
|
89
89
|
apiType: 'semp',
|
|
90
90
|
authType: broker.authType === AuthType.BASIC ? 'basic' : 'bearer',
|
|
@@ -133,8 +133,8 @@ export class BrokerAuthManager {
|
|
|
133
133
|
}
|
|
134
134
|
else {
|
|
135
135
|
// Create new storage with new salt
|
|
136
|
-
const salt =
|
|
137
|
-
this.encryptionKey = await
|
|
136
|
+
const salt = AuthEncryption.generateSalt();
|
|
137
|
+
this.encryptionKey = await AuthEncryption.deriveKey(combinedKey, salt);
|
|
138
138
|
this.storage = {
|
|
139
139
|
brokers: [],
|
|
140
140
|
version: '1.0.0',
|
|
@@ -225,9 +225,9 @@ export class BrokerAuthManager {
|
|
|
225
225
|
const encryptedData = JSON.parse(fileContent);
|
|
226
226
|
// Derive key from combined key and stored salt
|
|
227
227
|
const salt = Buffer.from(encryptedData.salt, 'base64');
|
|
228
|
-
this.encryptionKey = await
|
|
228
|
+
this.encryptionKey = await AuthEncryption.deriveKey(combinedKey, salt);
|
|
229
229
|
// Decrypt storage
|
|
230
|
-
this.storage = await
|
|
230
|
+
this.storage = await AuthEncryption.decrypt(encryptedData, this.encryptionKey);
|
|
231
231
|
}
|
|
232
232
|
catch (error) {
|
|
233
233
|
if (error instanceof BrokerAuthError) {
|
|
@@ -247,11 +247,11 @@ export class BrokerAuthManager {
|
|
|
247
247
|
// Ensure directory exists
|
|
248
248
|
await mkdir(this.configDir, { mode: 0o700, recursive: true });
|
|
249
249
|
// Encrypt data
|
|
250
|
-
const encrypted = await
|
|
250
|
+
const encrypted = await AuthEncryption.encrypt(this.storage, this.encryptionKey);
|
|
251
251
|
// Re-derive key with new salt for next save
|
|
252
252
|
const combinedKey = `${this.masterKey}:${this.machineId}`;
|
|
253
253
|
const newSalt = Buffer.from(encrypted.salt, 'base64');
|
|
254
|
-
this.encryptionKey = await
|
|
254
|
+
this.encryptionKey = await AuthEncryption.deriveKey(combinedKey, newSalt);
|
|
255
255
|
// Write to temp file first (atomic write)
|
|
256
256
|
const jsonData = JSON.stringify(encrypted, null, 2);
|
|
257
257
|
const tempFile = `${this.configFile}.tmp`;
|
|
@@ -294,19 +294,13 @@ export class BrokerAuthManager {
|
|
|
294
294
|
if (broker.sempPort < 1 || broker.sempPort > 65_535) {
|
|
295
295
|
throw new BrokerAuthError('SEMP port must be between 1 and 65535', BrokerAuthErrorCode.INVALID_PORT);
|
|
296
296
|
}
|
|
297
|
-
// Validate auth
|
|
298
|
-
if (broker.authType
|
|
299
|
-
if (!broker.accessToken || !broker.clientId) {
|
|
300
|
-
throw new BrokerAuthError('OAuth brokers require accessToken and clientId', BrokerAuthErrorCode.INVALID_OAUTH_CONFIG);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
else if (broker.authType === AuthType.BASIC) {
|
|
304
|
-
if (!broker.encodedCredentials) {
|
|
305
|
-
throw new BrokerAuthError('Basic auth brokers require encodedCredentials', BrokerAuthErrorCode.INVALID_BASIC_CONFIG);
|
|
306
|
-
}
|
|
307
|
-
}
|
|
308
|
-
else {
|
|
297
|
+
// Validate auth type
|
|
298
|
+
if (broker.authType !== AuthType.OAUTH && broker.authType !== AuthType.BASIC) {
|
|
309
299
|
throw new BrokerAuthError('Invalid auth type', BrokerAuthErrorCode.INVALID_AUTH_TYPE);
|
|
310
300
|
}
|
|
301
|
+
// Validate access token
|
|
302
|
+
if (!broker.accessToken || broker.accessToken.trim() === '') {
|
|
303
|
+
throw new BrokerAuthError('Access token is required', BrokerAuthErrorCode.INVALID_ACCESS_TOKEN);
|
|
304
|
+
}
|
|
311
305
|
}
|
|
312
306
|
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication types supported by the broker auth system
|
|
3
|
+
*/
|
|
4
|
+
export declare enum AuthType {
|
|
5
|
+
BASIC = "basic",
|
|
6
|
+
OAUTH = "oauth"
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Broker authentication configuration
|
|
10
|
+
*
|
|
11
|
+
* @property authType - Type of authentication (BASIC or OAUTH)
|
|
12
|
+
* @property name - Human-readable name/alias for the broker
|
|
13
|
+
* @property sempEndpoint - SEMP endpoint URL (must start with http:// or https://)
|
|
14
|
+
* @property sempPort - SEMP port number (1-65535)
|
|
15
|
+
* @property accessToken - For OAuth: access token string. For Basic: base64-encoded credentials
|
|
16
|
+
*/
|
|
17
|
+
export interface BrokerAuth {
|
|
18
|
+
accessToken: string;
|
|
19
|
+
authType: AuthType;
|
|
20
|
+
name: string;
|
|
21
|
+
sempEndpoint: string;
|
|
22
|
+
sempPort: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Storage format for broker configurations
|
|
26
|
+
*/
|
|
27
|
+
export interface BrokerAuthStorage {
|
|
28
|
+
brokers: BrokerAuth[];
|
|
29
|
+
version: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Error codes for broker auth operations
|
|
33
|
+
*/
|
|
34
|
+
export declare enum BrokerAuthErrorCode {
|
|
35
|
+
BROKER_ALREADY_EXISTS = "BROKER_ALREADY_EXISTS",
|
|
36
|
+
BROKER_NOT_FOUND = "BROKER_NOT_FOUND",
|
|
37
|
+
DECRYPTION_FAILED = "DECRYPTION_FAILED",
|
|
38
|
+
ENCRYPTION_FAILED = "ENCRYPTION_FAILED",
|
|
39
|
+
FILE_READ_ERROR = "FILE_READ_ERROR",
|
|
40
|
+
FILE_WRITE_ERROR = "FILE_WRITE_ERROR",
|
|
41
|
+
INVALID_ACCESS_TOKEN = "INVALID_ACCESS_TOKEN",
|
|
42
|
+
INVALID_AUTH_TYPE = "INVALID_AUTH_TYPE",
|
|
43
|
+
INVALID_ENDPOINT = "INVALID_ENDPOINT",
|
|
44
|
+
INVALID_NAME = "INVALID_NAME",
|
|
45
|
+
INVALID_PASSWORD = "INVALID_PASSWORD",
|
|
46
|
+
INVALID_PORT = "INVALID_PORT",
|
|
47
|
+
NOT_INITIALIZED = "NOT_INITIALIZED"
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Custom error class for broker authentication operations
|
|
51
|
+
*/
|
|
52
|
+
export declare class BrokerAuthError extends Error {
|
|
53
|
+
readonly code: BrokerAuthErrorCode;
|
|
54
|
+
readonly cause?: Error | undefined;
|
|
55
|
+
constructor(message: string, code: BrokerAuthErrorCode, cause?: Error | undefined);
|
|
56
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Authentication types supported by the broker auth system
|
|
3
|
+
*/
|
|
4
|
+
export var AuthType;
|
|
5
|
+
(function (AuthType) {
|
|
6
|
+
AuthType["BASIC"] = "basic";
|
|
7
|
+
AuthType["OAUTH"] = "oauth";
|
|
8
|
+
})(AuthType || (AuthType = {}));
|
|
9
|
+
/**
|
|
10
|
+
* Error codes for broker auth operations
|
|
11
|
+
*/
|
|
12
|
+
export var BrokerAuthErrorCode;
|
|
13
|
+
(function (BrokerAuthErrorCode) {
|
|
14
|
+
BrokerAuthErrorCode["BROKER_ALREADY_EXISTS"] = "BROKER_ALREADY_EXISTS";
|
|
15
|
+
BrokerAuthErrorCode["BROKER_NOT_FOUND"] = "BROKER_NOT_FOUND";
|
|
16
|
+
BrokerAuthErrorCode["DECRYPTION_FAILED"] = "DECRYPTION_FAILED";
|
|
17
|
+
BrokerAuthErrorCode["ENCRYPTION_FAILED"] = "ENCRYPTION_FAILED";
|
|
18
|
+
BrokerAuthErrorCode["FILE_READ_ERROR"] = "FILE_READ_ERROR";
|
|
19
|
+
BrokerAuthErrorCode["FILE_WRITE_ERROR"] = "FILE_WRITE_ERROR";
|
|
20
|
+
BrokerAuthErrorCode["INVALID_ACCESS_TOKEN"] = "INVALID_ACCESS_TOKEN";
|
|
21
|
+
BrokerAuthErrorCode["INVALID_AUTH_TYPE"] = "INVALID_AUTH_TYPE";
|
|
22
|
+
BrokerAuthErrorCode["INVALID_ENDPOINT"] = "INVALID_ENDPOINT";
|
|
23
|
+
BrokerAuthErrorCode["INVALID_NAME"] = "INVALID_NAME";
|
|
24
|
+
BrokerAuthErrorCode["INVALID_PASSWORD"] = "INVALID_PASSWORD";
|
|
25
|
+
BrokerAuthErrorCode["INVALID_PORT"] = "INVALID_PORT";
|
|
26
|
+
BrokerAuthErrorCode["NOT_INITIALIZED"] = "NOT_INITIALIZED";
|
|
27
|
+
})(BrokerAuthErrorCode || (BrokerAuthErrorCode = {}));
|
|
28
|
+
/**
|
|
29
|
+
* Custom error class for broker authentication operations
|
|
30
|
+
*/
|
|
31
|
+
export class BrokerAuthError extends Error {
|
|
32
|
+
code;
|
|
33
|
+
cause;
|
|
34
|
+
constructor(message, code, cause) {
|
|
35
|
+
super(message);
|
|
36
|
+
this.code = code;
|
|
37
|
+
this.cause = cause;
|
|
38
|
+
this.name = 'BrokerAuthError';
|
|
39
|
+
}
|
|
40
|
+
}
|
package/lib/auth/index.d.ts
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
* Authentication management module
|
|
3
3
|
* Provides encrypted storage for broker and organization credentials
|
|
4
4
|
*/
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
7
|
-
export { AuthType, type
|
|
5
|
+
export { AuthEncryption } from './auth-encryption.js';
|
|
6
|
+
export { type EncryptedData, type EncryptionMetadata } from './auth-types.js';
|
|
7
|
+
export { AuthType, type BrokerAuth, BrokerAuthError, BrokerAuthErrorCode, type BrokerAuthStorage, } from './broker-auth-types.js';
|
|
8
|
+
export { BrokerAuthManager } from './broker-auth-manager.js';
|
|
8
9
|
export { OrgManager } from './org-manager.js';
|
|
9
10
|
export { type OrgConfig, OrgError, OrgErrorCode, type OrgStorage } from './org-types.js';
|
package/lib/auth/index.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* Authentication management module
|
|
3
3
|
* Provides encrypted storage for broker and organization credentials
|
|
4
4
|
*/
|
|
5
|
-
export {
|
|
6
|
-
export {
|
|
7
|
-
export {
|
|
5
|
+
export { AuthEncryption } from './auth-encryption.js';
|
|
6
|
+
export { AuthType, BrokerAuthError, BrokerAuthErrorCode, } from './broker-auth-types.js';
|
|
7
|
+
export { BrokerAuthManager } from './broker-auth-manager.js';
|
|
8
8
|
export { OrgManager } from './org-manager.js';
|
|
9
9
|
export { OrgError, OrgErrorCode } from './org-types.js';
|
package/lib/auth/org-manager.js
CHANGED
|
@@ -3,7 +3,7 @@ import { homedir } from 'node:os';
|
|
|
3
3
|
import { join } from 'node:path';
|
|
4
4
|
import { DefaultBaseUrl, EnvironmentVariable, envVars } from '../config/env-vars.js';
|
|
5
5
|
import { ScConnection } from '../util/sc-connection.js';
|
|
6
|
-
import {
|
|
6
|
+
import { AuthEncryption } from './auth-encryption.js';
|
|
7
7
|
import { KeychainService } from './keychain.js';
|
|
8
8
|
import { OrgError, OrgErrorCode } from './org-types.js';
|
|
9
9
|
const SERVICE_NAME = 'local';
|
|
@@ -151,8 +151,8 @@ export class OrgManager {
|
|
|
151
151
|
}
|
|
152
152
|
else {
|
|
153
153
|
// Create new storage with new salt
|
|
154
|
-
const salt =
|
|
155
|
-
this.encryptionKey = await
|
|
154
|
+
const salt = AuthEncryption.generateSalt();
|
|
155
|
+
this.encryptionKey = await AuthEncryption.deriveKey(combinedKey, salt);
|
|
156
156
|
this.storage = {
|
|
157
157
|
orgs: [],
|
|
158
158
|
version: '1.0.0',
|
|
@@ -280,9 +280,9 @@ export class OrgManager {
|
|
|
280
280
|
const encryptedData = JSON.parse(fileContent);
|
|
281
281
|
// Derive key from combined key and stored salt
|
|
282
282
|
const salt = Buffer.from(encryptedData.salt, 'base64');
|
|
283
|
-
this.encryptionKey = await
|
|
283
|
+
this.encryptionKey = await AuthEncryption.deriveKey(combinedKey, salt);
|
|
284
284
|
// Decrypt storage
|
|
285
|
-
this.storage = await
|
|
285
|
+
this.storage = await AuthEncryption.decrypt(encryptedData, this.encryptionKey);
|
|
286
286
|
}
|
|
287
287
|
catch (error) {
|
|
288
288
|
if (error instanceof OrgError) {
|
|
@@ -316,10 +316,10 @@ export class OrgManager {
|
|
|
316
316
|
await mkdir(this.configDir, { mode: 0o700, recursive: true });
|
|
317
317
|
// Generate new salt and derive key for THIS save
|
|
318
318
|
const combinedKey = `${this.masterKey}:${this.machineId}`;
|
|
319
|
-
const newSalt =
|
|
320
|
-
const newKey = await
|
|
319
|
+
const newSalt = AuthEncryption.generateSalt();
|
|
320
|
+
const newKey = await AuthEncryption.deriveKey(combinedKey, newSalt);
|
|
321
321
|
// Encrypt data with the new key
|
|
322
|
-
const encrypted = await
|
|
322
|
+
const encrypted = await AuthEncryption.encrypt(this.storage, newKey);
|
|
323
323
|
// Update the salt in encrypted data to match the salt we used for key derivation
|
|
324
324
|
encrypted.salt = newSalt.toString('base64');
|
|
325
325
|
// Store the new key for next operation
|
package/lib/exported.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AuthType, type
|
|
1
|
+
export { AuthType, type BrokerAuth, BrokerAuthError, BrokerAuthErrorCode, BrokerAuthManager, type OrgConfig, OrgError, OrgErrorCode, OrgManager, type OrgStorage, } from './auth/index.js';
|
|
2
2
|
export { EnvironmentVariable, envVars } from './config/env-vars.js';
|
|
3
3
|
export { ScCommand } from './sc-command.js';
|
|
4
4
|
export { type ApiType, type HttpAuthType, ScConnection, type ScConnectionOptions } from './util/sc-connection.js';
|
package/lib/sc-command.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Command, Interfaces } from '@oclif/core';
|
|
2
|
-
import { BrokerAuthManager } from './auth/auth-manager.js';
|
|
2
|
+
import { BrokerAuthManager } from './auth/broker-auth-manager.js';
|
|
3
3
|
import { OrgManager } from './auth/org-manager.js';
|
|
4
4
|
export type Flags<T extends typeof Command> = Interfaces.InferredFlags<(typeof ScCommand)['baseFlags'] & T['flags']>;
|
|
5
5
|
export type Args<T extends typeof Command> = Interfaces.InferredArgs<T['args']>;
|
package/lib/sc-command.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Command, Flags } from '@oclif/core';
|
|
2
|
-
import { BrokerAuthManager } from './auth/auth-manager.js';
|
|
2
|
+
import { BrokerAuthManager } from './auth/broker-auth-manager.js';
|
|
3
3
|
import { OrgManager } from './auth/org-manager.js';
|
|
4
4
|
/**
|
|
5
5
|
* A base command that provided common functionality for all sc commands.
|