latchkey 1.0.1 → 2.0.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/README.md +27 -7
- package/dist/integrations/SKILL.md +9 -2
- package/dist/package.json +1 -1
- package/dist/src/apiCredentialStore.d.ts +1 -1
- package/dist/src/apiCredentialStore.d.ts.map +1 -1
- package/dist/src/apiCredentialStore.js +1 -1
- package/dist/src/apiCredentialStore.js.map +1 -1
- package/dist/src/apiCredentials.d.ts +11 -114
- package/dist/src/apiCredentials.d.ts.map +1 -1
- package/dist/src/apiCredentials.js +9 -101
- package/dist/src/apiCredentials.js.map +1 -1
- package/dist/src/apiCredentialsSerialization.d.ts +119 -0
- package/dist/src/apiCredentialsSerialization.d.ts.map +1 -0
- package/dist/src/apiCredentialsSerialization.js +90 -0
- package/dist/src/apiCredentialsSerialization.js.map +1 -0
- package/dist/src/browserConfig.d.ts +1 -5
- package/dist/src/browserConfig.d.ts.map +1 -1
- package/dist/src/browserConfig.js +2 -8
- package/dist/src/browserConfig.js.map +1 -1
- package/dist/src/cli.js +20 -0
- package/dist/src/cli.js.map +1 -1
- package/dist/src/cliCommands.d.ts +0 -1
- package/dist/src/cliCommands.d.ts.map +1 -1
- package/dist/src/cliCommands.js +50 -40
- package/dist/src/cliCommands.js.map +1 -1
- package/dist/src/config.d.ts +4 -3
- package/dist/src/config.d.ts.map +1 -1
- package/dist/src/config.js +17 -23
- package/dist/src/config.js.map +1 -1
- package/dist/src/curl.d.ts +10 -0
- package/dist/src/curl.d.ts.map +1 -1
- package/dist/src/curl.js +88 -0
- package/dist/src/curl.js.map +1 -1
- package/dist/src/encryptedStorage.d.ts +9 -0
- package/dist/src/encryptedStorage.d.ts.map +1 -1
- package/dist/src/encryptedStorage.js +12 -0
- package/dist/src/encryptedStorage.js.map +1 -1
- package/dist/src/index.d.ts +4 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +4 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/migrations.d.ts +9 -0
- package/dist/src/migrations.d.ts.map +1 -0
- package/dist/src/migrations.js +77 -0
- package/dist/src/migrations.js.map +1 -0
- package/dist/src/oauthUtils.d.ts +4 -1
- package/dist/src/oauthUtils.d.ts.map +1 -1
- package/dist/src/oauthUtils.js.map +1 -1
- package/dist/src/playwrightUtils.d.ts +2 -2
- package/dist/src/playwrightUtils.d.ts.map +1 -1
- package/dist/src/playwrightUtils.js +4 -4
- package/dist/src/playwrightUtils.js.map +1 -1
- package/dist/src/registry.d.ts.map +1 -1
- package/dist/src/registry.js +18 -2
- package/dist/src/registry.js.map +1 -1
- package/dist/src/services/aws.d.ts +44 -0
- package/dist/src/services/aws.d.ts.map +1 -0
- package/dist/src/services/aws.js +237 -0
- package/dist/src/services/aws.js.map +1 -0
- package/dist/src/services/base.d.ts +14 -0
- package/dist/src/services/base.d.ts.map +1 -1
- package/dist/src/services/base.js +23 -11
- package/dist/src/services/base.js.map +1 -1
- package/dist/src/services/calendly.d.ts +12 -0
- package/dist/src/services/calendly.d.ts.map +1 -0
- package/dist/src/services/calendly.js +18 -0
- package/dist/src/services/calendly.js.map +1 -0
- package/dist/src/services/discord.d.ts +1 -0
- package/dist/src/services/discord.d.ts.map +1 -1
- package/dist/src/services/discord.js +3 -0
- package/dist/src/services/discord.js.map +1 -1
- package/dist/src/services/dropbox.d.ts +2 -1
- package/dist/src/services/dropbox.d.ts.map +1 -1
- package/dist/src/services/dropbox.js +5 -0
- package/dist/src/services/dropbox.js.map +1 -1
- package/dist/src/services/figma.d.ts +12 -0
- package/dist/src/services/figma.d.ts.map +1 -0
- package/dist/src/services/figma.js +14 -0
- package/dist/src/services/figma.js.map +1 -0
- package/dist/src/services/github.d.ts +1 -0
- package/dist/src/services/github.d.ts.map +1 -1
- package/dist/src/services/github.js +3 -0
- package/dist/src/services/github.js.map +1 -1
- package/dist/src/services/gitlab.d.ts +12 -0
- package/dist/src/services/gitlab.d.ts.map +1 -0
- package/dist/src/services/gitlab.js +14 -0
- package/dist/src/services/gitlab.js.map +1 -0
- package/dist/src/services/google/analytics.d.ts +11 -0
- package/dist/src/services/google/analytics.d.ts.map +1 -0
- package/dist/src/services/google/analytics.js +22 -0
- package/dist/src/services/google/analytics.js.map +1 -0
- package/dist/src/services/google/base.d.ts +73 -0
- package/dist/src/services/google/base.d.ts.map +1 -0
- package/dist/src/services/google/base.js +323 -0
- package/dist/src/services/google/base.js.map +1 -0
- package/dist/src/services/google/calendar.d.ts +11 -0
- package/dist/src/services/google/calendar.d.ts.map +1 -0
- package/dist/src/services/google/calendar.js +22 -0
- package/dist/src/services/google/calendar.js.map +1 -0
- package/dist/src/services/google/directions.d.ts +14 -0
- package/dist/src/services/google/directions.d.ts.map +1 -0
- package/dist/src/services/google/directions.js +49 -0
- package/dist/src/services/google/directions.js.map +1 -0
- package/dist/src/services/google/docs.d.ts +11 -0
- package/dist/src/services/google/docs.d.ts.map +1 -0
- package/dist/src/services/google/docs.js +19 -0
- package/dist/src/services/google/docs.js.map +1 -0
- package/dist/src/services/google/drive.d.ts +11 -0
- package/dist/src/services/google/drive.d.ts.map +1 -0
- package/dist/src/services/google/drive.js +19 -0
- package/dist/src/services/google/drive.js.map +1 -0
- package/dist/src/services/google/gmail.d.ts +11 -0
- package/dist/src/services/google/gmail.d.ts.map +1 -0
- package/dist/src/services/google/gmail.js +24 -0
- package/dist/src/services/google/gmail.js.map +1 -0
- package/dist/src/services/google/maps.d.ts +39 -0
- package/dist/src/services/google/maps.d.ts.map +1 -0
- package/dist/src/services/google/maps.js +94 -0
- package/dist/src/services/google/maps.js.map +1 -0
- package/dist/src/services/google/people.d.ts +11 -0
- package/dist/src/services/google/people.d.ts.map +1 -0
- package/dist/src/services/google/people.js +22 -0
- package/dist/src/services/google/people.js.map +1 -0
- package/dist/src/services/google/sheets.d.ts +11 -0
- package/dist/src/services/google/sheets.d.ts.map +1 -0
- package/dist/src/services/google/sheets.js +19 -0
- package/dist/src/services/google/sheets.js.map +1 -0
- package/dist/src/services/googleAnalytics.d.ts +11 -0
- package/dist/src/services/googleAnalytics.d.ts.map +1 -0
- package/dist/src/services/googleAnalytics.js +18 -0
- package/dist/src/services/googleAnalytics.js.map +1 -0
- package/dist/src/services/googleMaps.d.ts +12 -0
- package/dist/src/services/googleMaps.d.ts.map +1 -0
- package/dist/src/services/googleMaps.js +17 -0
- package/dist/src/services/googleMaps.js.map +1 -0
- package/dist/src/services/index.d.ts +19 -2
- package/dist/src/services/index.d.ts.map +1 -1
- package/dist/src/services/index.js +19 -2
- package/dist/src/services/index.js.map +1 -1
- package/dist/src/services/linear.d.ts +1 -0
- package/dist/src/services/linear.d.ts.map +1 -1
- package/dist/src/services/linear.js +3 -0
- package/dist/src/services/linear.js.map +1 -1
- package/dist/src/services/mailchimp.d.ts +2 -1
- package/dist/src/services/mailchimp.d.ts.map +1 -1
- package/dist/src/services/mailchimp.js +4 -3
- package/dist/src/services/mailchimp.js.map +1 -1
- package/dist/src/services/notion.d.ts +1 -0
- package/dist/src/services/notion.d.ts.map +1 -1
- package/dist/src/services/notion.js +3 -0
- package/dist/src/services/notion.js.map +1 -1
- package/dist/src/services/sentry.d.ts +14 -0
- package/dist/src/services/sentry.d.ts.map +1 -0
- package/dist/src/services/sentry.js +43 -0
- package/dist/src/services/sentry.js.map +1 -0
- package/dist/src/services/slack.d.ts +30 -1
- package/dist/src/services/slack.d.ts.map +1 -1
- package/dist/src/services/slack.js +45 -2
- package/dist/src/services/slack.js.map +1 -1
- package/dist/src/services/stripe.d.ts +12 -0
- package/dist/src/services/stripe.d.ts.map +1 -0
- package/dist/src/services/stripe.js +14 -0
- package/dist/src/services/stripe.js.map +1 -0
- package/dist/src/services/telegram.d.ts +40 -0
- package/dist/src/services/telegram.d.ts.map +1 -0
- package/dist/src/services/telegram.js +73 -0
- package/dist/src/services/telegram.js.map +1 -0
- package/dist/src/services/yelp.d.ts +12 -0
- package/dist/src/services/yelp.d.ts.map +1 -0
- package/dist/src/services/yelp.js +16 -0
- package/dist/src/services/yelp.js.map +1 -0
- package/dist/src/services/zoom.d.ts +12 -0
- package/dist/src/services/zoom.d.ts.map +1 -0
- package/dist/src/services/zoom.js +18 -0
- package/dist/src/services/zoom.js.map +1 -0
- package/dist/tests/apiCredentialStore.test.js +2 -19
- package/dist/tests/apiCredentialStore.test.js.map +1 -1
- package/dist/tests/apiCredentials.test.js +139 -178
- package/dist/tests/apiCredentials.test.js.map +1 -1
- package/dist/tests/cli.test.js +160 -260
- package/dist/tests/cli.test.js.map +1 -1
- package/dist/tests/encryptedStorage.test.js +0 -4
- package/dist/tests/encryptedStorage.test.js.map +1 -1
- package/dist/tests/encryptedStorageKeyGeneration.test.d.ts +2 -0
- package/dist/tests/encryptedStorageKeyGeneration.test.d.ts.map +1 -0
- package/dist/tests/encryptedStorageKeyGeneration.test.js +22 -0
- package/dist/tests/encryptedStorageKeyGeneration.test.js.map +1 -0
- package/dist/tests/encryption.test.js +3 -35
- package/dist/tests/encryption.test.js.map +1 -1
- package/dist/tests/migrations.test.d.ts +2 -0
- package/dist/tests/migrations.test.d.ts.map +1 -0
- package/dist/tests/migrations.test.js +164 -0
- package/dist/tests/migrations.test.js.map +1 -0
- package/dist/tests/playwrightDownload.test.js +2 -65
- package/dist/tests/playwrightDownload.test.js.map +1 -1
- package/dist/tests/registry.test.js +49 -75
- package/dist/tests/registry.test.js.map +1 -1
- package/dist/tests/servicesAgainstRecordings.test.js +1 -1
- package/dist/tests/servicesAgainstRecordings.test.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,80 +1,40 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { AuthorizationBearer, AuthorizationBare,
|
|
2
|
+
import { AuthorizationBearer, AuthorizationBare, RawCurlCredentials, } from '../src/apiCredentials.js';
|
|
3
|
+
import { deserializeCredentials, serializeCredentials, ApiCredentialsSchema, } from '../src/apiCredentialsSerialization.js';
|
|
4
|
+
import { SlackApiCredentials } from '../src/services/slack.js';
|
|
5
|
+
import { TelegramBotCredentials } from '../src/services/telegram.js';
|
|
6
|
+
import { AwsCredentials } from '../src/services/aws.js';
|
|
7
|
+
import { GoogleApiKeyCredentials } from '../src/services/google/base.js';
|
|
3
8
|
describe('AuthorizationBearer', () => {
|
|
4
|
-
it('should
|
|
9
|
+
it('should inject Bearer token header', () => {
|
|
5
10
|
const credentials = new AuthorizationBearer('test-token-123');
|
|
6
|
-
expect(credentials.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
expect(credentials.toJSON()).toEqual({
|
|
11
|
-
objectType: 'authorizationBearer',
|
|
12
|
-
token: 'test-token-123',
|
|
13
|
-
});
|
|
14
|
-
});
|
|
15
|
-
it('should deserialize from JSON', () => {
|
|
16
|
-
const data = {
|
|
17
|
-
objectType: 'authorizationBearer',
|
|
18
|
-
token: 'test-token-123',
|
|
19
|
-
};
|
|
20
|
-
const credentials = AuthorizationBearer.fromJSON(data);
|
|
21
|
-
expect(credentials.token).toBe('test-token-123');
|
|
11
|
+
expect(credentials.injectIntoCurlCall([])).toEqual([
|
|
12
|
+
'-H',
|
|
13
|
+
'Authorization: Bearer test-token-123',
|
|
14
|
+
]);
|
|
22
15
|
});
|
|
23
16
|
});
|
|
24
17
|
describe('AuthorizationBare', () => {
|
|
25
|
-
it('should
|
|
18
|
+
it('should inject raw Authorization header', () => {
|
|
26
19
|
const credentials = new AuthorizationBare('raw-token-456');
|
|
27
|
-
expect(credentials.
|
|
28
|
-
});
|
|
29
|
-
it('should serialize to JSON', () => {
|
|
30
|
-
const credentials = new AuthorizationBare('raw-token-456');
|
|
31
|
-
expect(credentials.toJSON()).toEqual({
|
|
32
|
-
objectType: 'authorizationBare',
|
|
33
|
-
token: 'raw-token-456',
|
|
34
|
-
});
|
|
35
|
-
});
|
|
36
|
-
it('should deserialize from JSON', () => {
|
|
37
|
-
const data = {
|
|
38
|
-
objectType: 'authorizationBare',
|
|
39
|
-
token: 'raw-token-456',
|
|
40
|
-
};
|
|
41
|
-
const credentials = AuthorizationBare.fromJSON(data);
|
|
42
|
-
expect(credentials.token).toBe('raw-token-456');
|
|
20
|
+
expect(credentials.injectIntoCurlCall([])).toEqual(['-H', 'Authorization: raw-token-456']);
|
|
43
21
|
});
|
|
44
22
|
});
|
|
45
23
|
describe('SlackApiCredentials', () => {
|
|
46
|
-
it('should
|
|
24
|
+
it('should inject token and cookie headers', () => {
|
|
47
25
|
const credentials = new SlackApiCredentials('xoxc-token', 'd-cookie-value');
|
|
48
|
-
expect(credentials.
|
|
26
|
+
expect(credentials.injectIntoCurlCall([])).toEqual([
|
|
49
27
|
'-H',
|
|
50
28
|
'Authorization: Bearer xoxc-token',
|
|
51
29
|
'-H',
|
|
52
30
|
'Cookie: d=d-cookie-value',
|
|
53
31
|
]);
|
|
54
32
|
});
|
|
55
|
-
it('should serialize to JSON', () => {
|
|
56
|
-
const credentials = new SlackApiCredentials('xoxc-token', 'd-cookie-value');
|
|
57
|
-
expect(credentials.toJSON()).toEqual({
|
|
58
|
-
objectType: 'slack',
|
|
59
|
-
token: 'xoxc-token',
|
|
60
|
-
dCookie: 'd-cookie-value',
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
it('should deserialize from JSON', () => {
|
|
64
|
-
const data = {
|
|
65
|
-
objectType: 'slack',
|
|
66
|
-
token: 'xoxc-token',
|
|
67
|
-
dCookie: 'd-cookie-value',
|
|
68
|
-
};
|
|
69
|
-
const credentials = SlackApiCredentials.fromJSON(data);
|
|
70
|
-
expect(credentials.token).toBe('xoxc-token');
|
|
71
|
-
expect(credentials.dCookie).toBe('d-cookie-value');
|
|
72
|
-
});
|
|
73
33
|
});
|
|
74
34
|
describe('RawCurlCredentials', () => {
|
|
75
|
-
it('should
|
|
35
|
+
it('should inject raw curl arguments', () => {
|
|
76
36
|
const credentials = new RawCurlCredentials(['-H', 'X-Token: secret', '-H', 'X-Other: value']);
|
|
77
|
-
expect(credentials.
|
|
37
|
+
expect(credentials.injectIntoCurlCall([])).toEqual([
|
|
78
38
|
'-H',
|
|
79
39
|
'X-Token: secret',
|
|
80
40
|
'-H',
|
|
@@ -83,133 +43,140 @@ describe('RawCurlCredentials', () => {
|
|
|
83
43
|
});
|
|
84
44
|
it('should handle empty curl arguments', () => {
|
|
85
45
|
const credentials = new RawCurlCredentials([]);
|
|
86
|
-
expect(credentials.
|
|
87
|
-
});
|
|
88
|
-
it('should serialize to JSON', () => {
|
|
89
|
-
const credentials = new RawCurlCredentials(['-H', 'X-Token: secret']);
|
|
90
|
-
expect(credentials.toJSON()).toEqual({
|
|
91
|
-
objectType: 'rawCurl',
|
|
92
|
-
curlArguments: ['-H', 'X-Token: secret'],
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
it('should deserialize from JSON', () => {
|
|
96
|
-
const data = {
|
|
97
|
-
objectType: 'rawCurl',
|
|
98
|
-
curlArguments: ['-H', 'X-Token: secret'],
|
|
99
|
-
};
|
|
100
|
-
const credentials = RawCurlCredentials.fromJSON(data);
|
|
101
|
-
expect(credentials.curlArguments).toEqual(['-H', 'X-Token: secret']);
|
|
102
|
-
});
|
|
103
|
-
it('should return undefined for isExpired', () => {
|
|
104
|
-
const credentials = new RawCurlCredentials(['-H', 'X-Token: secret']);
|
|
105
|
-
expect(credentials.isExpired()).toBeUndefined();
|
|
46
|
+
expect(credentials.injectIntoCurlCall([])).toEqual([]);
|
|
106
47
|
});
|
|
107
48
|
});
|
|
108
|
-
describe('
|
|
109
|
-
it('should
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
const credentials = deserializeCredentials(data);
|
|
115
|
-
expect(credentials).toBeInstanceOf(AuthorizationBearer);
|
|
116
|
-
expect(credentials.token).toBe('bearer-token');
|
|
117
|
-
});
|
|
118
|
-
it('should deserialize AuthorizationBare', () => {
|
|
119
|
-
const data = {
|
|
120
|
-
objectType: 'authorizationBare',
|
|
121
|
-
token: 'bare-token',
|
|
122
|
-
};
|
|
123
|
-
const credentials = deserializeCredentials(data);
|
|
124
|
-
expect(credentials).toBeInstanceOf(AuthorizationBare);
|
|
125
|
-
expect(credentials.token).toBe('bare-token');
|
|
126
|
-
});
|
|
127
|
-
it('should deserialize SlackApiCredentials', () => {
|
|
128
|
-
const data = {
|
|
129
|
-
objectType: 'slack',
|
|
130
|
-
token: 'slack-token',
|
|
131
|
-
dCookie: 'slack-cookie',
|
|
132
|
-
};
|
|
133
|
-
const credentials = deserializeCredentials(data);
|
|
134
|
-
expect(credentials).toBeInstanceOf(SlackApiCredentials);
|
|
135
|
-
expect(credentials.token).toBe('slack-token');
|
|
136
|
-
expect(credentials.dCookie).toBe('slack-cookie');
|
|
137
|
-
});
|
|
138
|
-
it('should deserialize RawCurlCredentials', () => {
|
|
139
|
-
const data = {
|
|
140
|
-
objectType: 'rawCurl',
|
|
141
|
-
curlArguments: ['-H', 'X-Token: test'],
|
|
142
|
-
};
|
|
143
|
-
const credentials = deserializeCredentials(data);
|
|
144
|
-
expect(credentials).toBeInstanceOf(RawCurlCredentials);
|
|
145
|
-
expect(credentials.curlArguments).toEqual(['-H', 'X-Token: test']);
|
|
49
|
+
describe('TelegramBotCredentials', () => {
|
|
50
|
+
it('should inject token into telegram API URL path', () => {
|
|
51
|
+
const credentials = new TelegramBotCredentials('123456:ABC-DEF');
|
|
52
|
+
expect(credentials.injectIntoCurlCall(['https://api.telegram.org/getMe'])).toEqual([
|
|
53
|
+
'https://api.telegram.org/bot123456:ABC-DEF/getMe',
|
|
54
|
+
]);
|
|
146
55
|
});
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
token: 'test-token',
|
|
155
|
-
});
|
|
56
|
+
it('should not modify non-telegram URLs', () => {
|
|
57
|
+
const credentials = new TelegramBotCredentials('123456:ABC-DEF');
|
|
58
|
+
expect(credentials.injectIntoCurlCall([
|
|
59
|
+
'-H',
|
|
60
|
+
'Content-Type: application/json',
|
|
61
|
+
'https://other.example.com/api',
|
|
62
|
+
])).toEqual(['-H', 'Content-Type: application/json', 'https://other.example.com/api']);
|
|
156
63
|
});
|
|
157
|
-
it('should
|
|
158
|
-
const credentials = new
|
|
159
|
-
|
|
160
|
-
expect(data).toEqual({
|
|
161
|
-
objectType: 'authorizationBare',
|
|
162
|
-
token: 'test-token',
|
|
163
|
-
});
|
|
64
|
+
it('should preserve other curl arguments', () => {
|
|
65
|
+
const credentials = new TelegramBotCredentials('123456:ABC-DEF');
|
|
66
|
+
expect(credentials.injectIntoCurlCall(['-X', 'POST', 'https://api.telegram.org/getMe'])).toEqual(['-X', 'POST', 'https://api.telegram.org/bot123456:ABC-DEF/getMe']);
|
|
164
67
|
});
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
68
|
+
});
|
|
69
|
+
describe('GoogleApiKeyCredentials', () => {
|
|
70
|
+
it('should inject X-Goog-Api-Key header for googleapis.com URLs', () => {
|
|
71
|
+
const credentials = new GoogleApiKeyCredentials('AIzaSyTestKey123');
|
|
72
|
+
expect(credentials.injectIntoCurlCall(['https://routes.googleapis.com/directions/v2:computeRoutes'])).toEqual([
|
|
73
|
+
'-H',
|
|
74
|
+
'X-Goog-Api-Key: AIzaSyTestKey123',
|
|
75
|
+
'https://routes.googleapis.com/directions/v2:computeRoutes',
|
|
76
|
+
]);
|
|
173
77
|
});
|
|
174
|
-
it('should
|
|
175
|
-
const credentials = new
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
78
|
+
it('should not modify non-googleapis.com URLs', () => {
|
|
79
|
+
const credentials = new GoogleApiKeyCredentials('AIzaSyTestKey123');
|
|
80
|
+
expect(credentials.injectIntoCurlCall([
|
|
81
|
+
'-H',
|
|
82
|
+
'Content-Type: application/json',
|
|
83
|
+
'https://other.example.com/api',
|
|
84
|
+
])).toEqual(['-H', 'Content-Type: application/json', 'https://other.example.com/api']);
|
|
181
85
|
});
|
|
182
86
|
});
|
|
183
|
-
describe('
|
|
184
|
-
it('should
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
87
|
+
describe('AwsCredentials', () => {
|
|
88
|
+
it('should inject Authorization, x-amz-date, and x-amz-content-sha256 headers', () => {
|
|
89
|
+
const credentials = new AwsCredentials('AKIAIOSFODNN7EXAMPLE', 'wJalrXUtnFEMI/K7MDENG');
|
|
90
|
+
const result = credentials.injectIntoCurlCall([
|
|
91
|
+
'https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15',
|
|
92
|
+
]);
|
|
93
|
+
const resultStrings = result;
|
|
94
|
+
expect(resultStrings).toHaveLength(7);
|
|
95
|
+
expect(resultStrings[0]).toBe('-H');
|
|
96
|
+
expect(resultStrings[1]).toMatch(/^Authorization: AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE\//);
|
|
97
|
+
expect(resultStrings[2]).toBe('-H');
|
|
98
|
+
expect(resultStrings[3]).toMatch(/^x-amz-date: \d{8}T\d{6}Z$/);
|
|
99
|
+
expect(resultStrings[4]).toBe('-H');
|
|
100
|
+
expect(resultStrings[5]).toMatch(/^x-amz-content-sha256: [a-f0-9]{64}$/);
|
|
101
|
+
expect(resultStrings[6]).toBe('https://sts.amazonaws.com/?Action=GetCallerIdentity&Version=2011-06-15');
|
|
102
|
+
});
|
|
103
|
+
it('should include content-type in signed headers when present', () => {
|
|
104
|
+
const credentials = new AwsCredentials('AKIAIOSFODNN7EXAMPLE', 'wJalrXUtnFEMI/K7MDENG');
|
|
105
|
+
const result = credentials.injectIntoCurlCall([
|
|
106
|
+
'-H',
|
|
107
|
+
'Content-Type: application/json',
|
|
108
|
+
'-d',
|
|
109
|
+
'{}',
|
|
110
|
+
'https://lambda.us-east-1.amazonaws.com/2015-03-31/functions',
|
|
111
|
+
]);
|
|
112
|
+
const resultStrings = result;
|
|
113
|
+
const authHeader = resultStrings[1];
|
|
114
|
+
expect(authHeader).toContain('SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date');
|
|
115
|
+
});
|
|
116
|
+
it('should sign S3 virtual-hosted-style URLs with default region', () => {
|
|
117
|
+
const credentials = new AwsCredentials('AKIAIOSFODNN7EXAMPLE', 'wJalrXUtnFEMI/K7MDENG');
|
|
118
|
+
const result = credentials.injectIntoCurlCall([
|
|
119
|
+
'https://test-int8-transient.s3.amazonaws.com/',
|
|
120
|
+
]);
|
|
121
|
+
const resultStrings = result;
|
|
122
|
+
const authHeader = resultStrings[1];
|
|
123
|
+
// Credential scope must contain us-east-1/s3, not s3/test-int8-transient
|
|
124
|
+
expect(authHeader).toMatch(/Credential=AKIAIOSFODNN7EXAMPLE\/\d{8}\/us-east-1\/s3\//);
|
|
125
|
+
});
|
|
126
|
+
it('should sign S3 virtual-hosted-style URLs with explicit region', () => {
|
|
127
|
+
const credentials = new AwsCredentials('AKIAIOSFODNN7EXAMPLE', 'wJalrXUtnFEMI/K7MDENG');
|
|
128
|
+
const result = credentials.injectIntoCurlCall([
|
|
129
|
+
'https://test-int8-transient.s3.us-west-2.amazonaws.com/',
|
|
130
|
+
]);
|
|
131
|
+
const resultStrings = result;
|
|
132
|
+
const authHeader = resultStrings[1];
|
|
133
|
+
expect(authHeader).toMatch(/Credential=AKIAIOSFODNN7EXAMPLE\/\d{8}\/us-west-2\/s3\//);
|
|
190
134
|
});
|
|
191
|
-
it('should
|
|
192
|
-
const
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
});
|
|
196
|
-
expect(result.success).toBe(true);
|
|
135
|
+
it('should pass through arguments unchanged when no URL is present', () => {
|
|
136
|
+
const credentials = new AwsCredentials('AKIAIOSFODNN7EXAMPLE', 'wJalrXUtnFEMI/K7MDENG');
|
|
137
|
+
const result = credentials.injectIntoCurlCall(['-v']);
|
|
138
|
+
expect(result).toEqual(['-v']);
|
|
197
139
|
});
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
140
|
+
});
|
|
141
|
+
describe('serialization roundtrip', () => {
|
|
142
|
+
const cases = [
|
|
143
|
+
{ name: 'AuthorizationBearer', credentials: () => new AuthorizationBearer('test-token') },
|
|
144
|
+
{ name: 'AuthorizationBare', credentials: () => new AuthorizationBare('test-token') },
|
|
145
|
+
{
|
|
146
|
+
name: 'SlackApiCredentials',
|
|
147
|
+
credentials: () => new SlackApiCredentials('token', 'cookie'),
|
|
148
|
+
},
|
|
149
|
+
{
|
|
150
|
+
name: 'RawCurlCredentials',
|
|
151
|
+
credentials: () => new RawCurlCredentials(['-H', 'X-Token: test']),
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
name: 'TelegramBotCredentials',
|
|
155
|
+
credentials: () => new TelegramBotCredentials('123456:ABC-DEF'),
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: 'AwsCredentials',
|
|
159
|
+
credentials: () => new AwsCredentials('AKIAIOSFODNN7EXAMPLE', 'secret123'),
|
|
160
|
+
},
|
|
161
|
+
{
|
|
162
|
+
name: 'GoogleApiKeyCredentials',
|
|
163
|
+
credentials: () => new GoogleApiKeyCredentials('AIzaSyTestKey123'),
|
|
164
|
+
},
|
|
165
|
+
];
|
|
166
|
+
for (const { name, credentials: createCredentials } of cases) {
|
|
167
|
+
it(`should roundtrip ${name} through serialize/deserialize`, () => {
|
|
168
|
+
const original = createCredentials();
|
|
169
|
+
const serialized = serializeCredentials(original);
|
|
170
|
+
const deserialized = deserializeCredentials(serialized);
|
|
171
|
+
expect(deserialized).toBeInstanceOf(original.constructor);
|
|
172
|
+
expect(serializeCredentials(deserialized)).toEqual(serialized);
|
|
203
173
|
});
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
objectType: 'rawCurl',
|
|
209
|
-
curlArguments: ['-H', 'X-Token: test'],
|
|
174
|
+
it(`should validate ${name} with ApiCredentialsSchema`, () => {
|
|
175
|
+
const original = createCredentials();
|
|
176
|
+
const serialized = serializeCredentials(original);
|
|
177
|
+
expect(ApiCredentialsSchema.safeParse(serialized).success).toBe(true);
|
|
210
178
|
});
|
|
211
|
-
|
|
212
|
-
});
|
|
179
|
+
}
|
|
213
180
|
it('should reject invalid object type', () => {
|
|
214
181
|
const result = ApiCredentialsSchema.safeParse({
|
|
215
182
|
objectType: 'invalid',
|
|
@@ -217,11 +184,5 @@ describe('ApiCredentialsSchema', () => {
|
|
|
217
184
|
});
|
|
218
185
|
expect(result.success).toBe(false);
|
|
219
186
|
});
|
|
220
|
-
it('should reject missing token', () => {
|
|
221
|
-
const result = ApiCredentialsSchema.safeParse({
|
|
222
|
-
objectType: 'authorizationBearer',
|
|
223
|
-
});
|
|
224
|
-
expect(result.success).toBe(false);
|
|
225
|
-
});
|
|
226
187
|
});
|
|
227
188
|
//# sourceMappingURL=apiCredentials.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apiCredentials.test.js","sourceRoot":"","sources":["../../tests/apiCredentials.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,
|
|
1
|
+
{"version":3,"file":"apiCredentials.test.js","sourceRoot":"","sources":["../../tests/apiCredentials.test.ts"],"names":[],"mappings":"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"}
|