Skip to content

Commit 701ec10

Browse files
authored
Merge branch 'release/core-2' into ds.fix/core-2-always-free-default
2 parents f36ae38 + adb2a14 commit 701ec10

118 files changed

Lines changed: 2890 additions & 285 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

integration/tests/machine-auth/m2m.test.ts

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,9 @@ test.describe('machine-to-machine auth @machine', () => {
4242
4343
app.get('/api/protected', async (req, res) => {
4444
const token = req.get('Authorization')?.split(' ')[1];
45-
4645
try {
47-
const m2mToken = await clerkClient.m2m.verifyToken({ token });
48-
res.send('Protected response ' + m2mToken.id);
46+
const m2mToken = await clerkClient.m2m.verify({ token });
47+
res.send('Protected response ' + m2mToken.subject);
4948
} catch {
5049
res.status(401).send('Unauthorized');
5150
}
@@ -150,7 +149,7 @@ test.describe('machine-to-machine auth @machine', () => {
150149
},
151150
});
152151
expect(res.status()).toBe(200);
153-
expect(await res.text()).toBe('Protected response ' + emailServerM2MToken.id);
152+
expect(await res.text()).toBe('Protected response ' + emailServer.id);
154153

155154
// Analytics server can access primary API server after adding scope
156155
await u.services.clerk.machines.createScope(analyticsServer.id, primaryApiServer.id);
@@ -165,9 +164,30 @@ test.describe('machine-to-machine auth @machine', () => {
165164
},
166165
});
167166
expect(res2.status()).toBe(200);
168-
expect(await res2.text()).toBe('Protected response ' + m2mToken.id);
167+
expect(await res2.text()).toBe('Protected response ' + analyticsServer.id);
169168
await u.services.clerk.m2m.revokeToken({
170169
m2mTokenId: m2mToken.id,
171170
});
172171
});
172+
173+
test('verifies JWT format M2M token via local verification', async ({ page, context }) => {
174+
const u = createTestUtils({ app, page, context });
175+
176+
const client = createClerkClient({
177+
secretKey: instanceKeys.get('with-api-keys').sk,
178+
});
179+
const jwtToken = await client.m2m.createToken({
180+
machineSecretKey: emailServer.secretKey,
181+
secondsUntilExpiration: 60 * 30,
182+
tokenFormat: 'jwt',
183+
});
184+
185+
const res = await u.page.request.get(app.serverUrl + '/api/protected', {
186+
headers: { Authorization: `Bearer ${jwtToken.token}` },
187+
});
188+
expect(res.status()).toBe(200);
189+
expect(await res.text()).toBe('Protected response ' + emailServer.id);
190+
// JWT-format tokens are self-contained and not stored in BAPI, so revocation
191+
// is not applicable — they expire naturally via the exp claim.
192+
});
173193
});

packages/agent-toolkit/CHANGELOG.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
11
# @clerk/agent-toolkit
22

3+
## 0.2.28
4+
5+
### Patch Changes
6+
7+
- Updated dependencies [[`76a5a1b`](https://github.com/clerk/javascript/commit/76a5a1b851819b4247c944ba0132f2cacd626962), [`7955e9d`](https://github.com/clerk/javascript/commit/7955e9dd90419c02fd51226d4fe335d42e7096a5), [`51bc9a9`](https://github.com/clerk/javascript/commit/51bc9a90554b83f04b33e836931f33b778bfc506)]:
8+
- @clerk/backend@2.33.0
9+
- @clerk/shared@3.47.2
10+
- @clerk/types@4.101.20
11+
12+
## 0.2.27
13+
14+
### Patch Changes
15+
16+
- Updated dependencies [[`8a0c404`](https://github.com/clerk/javascript/commit/8a0c404d05a88697fcc3a609fef25bd5ff9f9ef0)]:
17+
- @clerk/shared@3.47.1
18+
- @clerk/backend@2.32.2
19+
- @clerk/types@4.101.19
20+
21+
## 0.2.26
22+
23+
### Patch Changes
24+
25+
- Updated dependencies [[`c15c8a2`](https://github.com/clerk/javascript/commit/c15c8a2cd263bd777fd94fb4bdeae2cfb4a70aca)]:
26+
- @clerk/backend@2.32.1
27+
28+
## 0.2.25
29+
30+
### Patch Changes
31+
32+
- Updated dependencies [[`c00c524`](https://github.com/clerk/javascript/commit/c00c5246f340cf0339c5725cade90cfcd118727d), [`9c935ad`](https://github.com/clerk/javascript/commit/9c935adeda94af60219ed8b7c7f1f9c34fbd410d)]:
33+
- @clerk/shared@3.47.0
34+
- @clerk/backend@2.32.0
35+
- @clerk/types@4.101.18
36+
337
## 0.2.24
438

539
### Patch Changes

packages/agent-toolkit/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@clerk/agent-toolkit",
3-
"version": "0.2.24",
3+
"version": "0.2.28",
44
"description": "Clerk Toolkit for AI Agents",
55
"homepage": "https://clerk.com/",
66
"bugs": {

packages/astro/CHANGELOG.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,39 @@
11
# @clerk/astro
22

3+
## 2.17.8
4+
5+
### Patch Changes
6+
7+
- Updated dependencies [[`76a5a1b`](https://github.com/clerk/javascript/commit/76a5a1b851819b4247c944ba0132f2cacd626962), [`7955e9d`](https://github.com/clerk/javascript/commit/7955e9dd90419c02fd51226d4fe335d42e7096a5), [`51bc9a9`](https://github.com/clerk/javascript/commit/51bc9a90554b83f04b33e836931f33b778bfc506)]:
8+
- @clerk/backend@2.33.0
9+
- @clerk/shared@3.47.2
10+
- @clerk/types@4.101.20
11+
12+
## 2.17.7
13+
14+
### Patch Changes
15+
16+
- Updated dependencies [[`8a0c404`](https://github.com/clerk/javascript/commit/8a0c404d05a88697fcc3a609fef25bd5ff9f9ef0)]:
17+
- @clerk/shared@3.47.1
18+
- @clerk/backend@2.32.2
19+
- @clerk/types@4.101.19
20+
21+
## 2.17.6
22+
23+
### Patch Changes
24+
25+
- Updated dependencies [[`c15c8a2`](https://github.com/clerk/javascript/commit/c15c8a2cd263bd777fd94fb4bdeae2cfb4a70aca)]:
26+
- @clerk/backend@2.32.1
27+
28+
## 2.17.5
29+
30+
### Patch Changes
31+
32+
- Updated dependencies [[`c00c524`](https://github.com/clerk/javascript/commit/c00c5246f340cf0339c5725cade90cfcd118727d), [`9c935ad`](https://github.com/clerk/javascript/commit/9c935adeda94af60219ed8b7c7f1f9c34fbd410d)]:
33+
- @clerk/shared@3.47.0
34+
- @clerk/backend@2.32.0
35+
- @clerk/types@4.101.18
36+
337
## 2.17.4
438

539
### Patch Changes

packages/astro/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@clerk/astro",
3-
"version": "2.17.4",
3+
"version": "2.17.8",
44
"description": "Clerk SDK for Astro",
55
"keywords": [
66
"auth",

packages/backend/CHANGELOG.md

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,115 @@
11
# Change Log
22

3+
## 2.33.0
4+
5+
### Minor Changes
6+
7+
- Added support for JWT token format when creating and verifying machine-to-machine (M2M) tokens. This enables fully **networkless verification** when using the public JWT key. ([#7883](https://github.com/clerk/javascript/pull/7883)) by [@wobsoriano](https://github.com/wobsoriano)
8+
9+
**Creating a JWT-format M2M token**
10+
11+
```ts
12+
const clerkClient = createClerkClient({
13+
machineSecretKey: process.env.CLERK_MACHINE_SECRET_KEY,
14+
});
15+
16+
const m2mToken = await clerkClient.m2m.createToken({
17+
tokenFormat: 'jwt',
18+
});
19+
20+
console.log('M2M token created:', m2mToken.token);
21+
```
22+
23+
**Verifying a token**
24+
25+
```ts
26+
const clerkClient = createClerkClient({
27+
machineSecretKey: process.env.CLERK_MACHINE_SECRET_KEY,
28+
});
29+
30+
const authHeader = req.headers.get('Authorization');
31+
const token = authHeader.slice(7);
32+
33+
const verified = await clerkClient.m2m.verify(token);
34+
35+
console.log('Verified M2M token:', verified);
36+
```
37+
38+
**Networkless verification**
39+
40+
```ts
41+
const clerkClient = createClerkClient({
42+
jwtKey: process.env.CLERK_JWT_KEY,
43+
});
44+
45+
const authHeader = req.headers.get('Authorization');
46+
const token = authHeader.slice(7);
47+
48+
const verified = await clerkClient.m2m.verify(token);
49+
50+
console.log('Verified M2M token:', verified);
51+
```
52+
53+
- Add `list()` method to M2M tokens API to retrieve a list of machine-to-machine tokens for a given machine. ([#7939](https://github.com/clerk/javascript/pull/7939)) by [@wobsoriano](https://github.com/wobsoriano)
54+
55+
```ts
56+
// Retrieve M2M tokens for a specific machine
57+
const response = await clerkClient.m2m.list({
58+
subject: 'mch_1xxxxxxxxxxxxx',
59+
});
60+
61+
console.log(response.data); // M2MToken[]
62+
console.log(response.totalCount); // number
63+
```
64+
65+
Filter by revoked or expired tokens:
66+
67+
```ts
68+
const revokedTokens = await clerkClient.m2m.list({
69+
subject: 'mch_1xxxxxxxxxxxxx',
70+
revoked: true,
71+
});
72+
73+
const expiredTokens = await clerkClient.m2m.list({
74+
subject: 'mch_1xxxxxxxxxxxxx',
75+
expired: true,
76+
});
77+
```
78+
79+
### Patch Changes
80+
81+
- Updated dependencies [[`7955e9d`](https://github.com/clerk/javascript/commit/7955e9dd90419c02fd51226d4fe335d42e7096a5)]:
82+
- @clerk/shared@3.47.2
83+
- @clerk/types@4.101.20
84+
85+
## 2.32.2
86+
87+
### Patch Changes
88+
89+
- Updated dependencies [[`8a0c404`](https://github.com/clerk/javascript/commit/8a0c404d05a88697fcc3a609fef25bd5ff9f9ef0)]:
90+
- @clerk/shared@3.47.1
91+
- @clerk/types@4.101.19
92+
93+
## 2.32.1
94+
95+
### Patch Changes
96+
97+
- Updates `OrganizationInvitationStatus` to include `expired` to match the API updates. ([#7909](https://github.com/clerk/javascript/pull/7909)) by [@austincalvelage](https://github.com/austincalvelage)
98+
99+
## 2.32.0
100+
101+
### Minor Changes
102+
103+
- Add support for Agent Tasks API endpoint which allows developers to create agent tasks that can be used to act on behalf of users through automated flows. ([#7897](https://github.com/clerk/javascript/pull/7897)) by [@tmilewski](https://github.com/tmilewski)
104+
105+
Export `createAgentTestingTask` helper for creating agent tasks via the Clerk Backend API from both `@clerk/testing/playwright` and `@clerk/testing/cypress` subpaths.
106+
107+
### Patch Changes
108+
109+
- Updated dependencies [[`c00c524`](https://github.com/clerk/javascript/commit/c00c5246f340cf0339c5725cade90cfcd118727d)]:
110+
- @clerk/shared@3.47.0
111+
- @clerk/types@4.101.18
112+
3113
## 2.31.2
4114

5115
### Patch Changes

packages/backend/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@clerk/backend",
3-
"version": "2.31.2",
3+
"version": "2.33.0",
44
"description": "Clerk Backend SDK - REST Client for Backend API & JWT verification utilities",
55
"homepage": "https://clerk.com/",
66
"bugs": {

packages/backend/src/__tests__/exports.test.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,9 @@ describe('subpath /internal exports', () => {
4949
"decorateObjectWithResources",
5050
"getAuthObjectForAcceptedToken",
5151
"getAuthObjectFromJwt",
52-
"getMachineTokenType",
5352
"invalidTokenAuthObject",
5453
"isMachineToken",
5554
"isMachineTokenByPrefix",
56-
"isMachineTokenType",
5755
"isTokenTypeAccepted",
5856
"makeAuthObjectSerializable",
5957
"reverificationError",
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import { http, HttpResponse } from 'msw';
2+
import { describe, expect, it } from 'vitest';
3+
4+
import { server, validateHeaders } from '../../mock-server';
5+
import { createBackendApiClient } from '../factory';
6+
7+
describe('AgentTaskAPI', () => {
8+
const apiClient = createBackendApiClient({
9+
apiUrl: 'https://api.clerk.test',
10+
secretKey: 'deadbeef',
11+
});
12+
13+
const mockAgentTaskResponse = {
14+
object: 'agent_task',
15+
agent_id: 'agent_123',
16+
task_id: 'task_456',
17+
url: 'https://example.com/agent-task',
18+
};
19+
20+
describe('create', () => {
21+
it('converts nested onBehalfOf.userId to snake_case', async () => {
22+
server.use(
23+
http.post(
24+
'https://api.clerk.test/v1/agents/tasks',
25+
validateHeaders(async ({ request }) => {
26+
const body = await request.json();
27+
28+
expect(body).toEqual({
29+
on_behalf_of: {
30+
user_id: 'user_123',
31+
},
32+
permissions: 'read,write',
33+
agent_name: 'test-agent',
34+
task_description: 'Test task',
35+
redirect_url: 'https://example.com/callback',
36+
session_max_duration_in_seconds: 1800,
37+
});
38+
39+
return HttpResponse.json(mockAgentTaskResponse);
40+
}),
41+
),
42+
);
43+
44+
const response = await apiClient.agentTasks.create({
45+
onBehalfOf: {
46+
userId: 'user_123',
47+
},
48+
permissions: 'read,write',
49+
agentName: 'test-agent',
50+
taskDescription: 'Test task',
51+
redirectUrl: 'https://example.com/callback',
52+
sessionMaxDurationInSeconds: 1800,
53+
});
54+
55+
expect(response.agentId).toBe('agent_123');
56+
expect(response.taskId).toBe('task_456');
57+
expect(response.url).toBe('https://example.com/agent-task');
58+
});
59+
60+
it('converts nested onBehalfOf.identifier to snake_case', async () => {
61+
server.use(
62+
http.post(
63+
'https://api.clerk.test/v1/agents/tasks',
64+
validateHeaders(async ({ request }) => {
65+
const body = await request.json();
66+
67+
expect(body).toEqual({
68+
on_behalf_of: {
69+
identifier: 'user@example.com',
70+
},
71+
permissions: 'read',
72+
agent_name: 'test-agent',
73+
task_description: 'Test task',
74+
redirect_url: 'https://example.com/callback',
75+
});
76+
77+
return HttpResponse.json(mockAgentTaskResponse);
78+
}),
79+
),
80+
);
81+
82+
const response = await apiClient.agentTasks.create({
83+
onBehalfOf: {
84+
identifier: 'user@example.com',
85+
},
86+
permissions: 'read',
87+
agentName: 'test-agent',
88+
taskDescription: 'Test task',
89+
redirectUrl: 'https://example.com/callback',
90+
});
91+
92+
expect(response.agentId).toBe('agent_123');
93+
expect(response.taskId).toBe('task_456');
94+
});
95+
});
96+
});

0 commit comments

Comments
 (0)