-
Notifications
You must be signed in to change notification settings - Fork 648
/
Copy pathclients.test.ts
144 lines (117 loc) · 5.06 KB
/
clients.test.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
import { OAuthRegisteredClientsStore } from './clients.js';
import { OAuthClientInformationFull } from '../../shared/auth.js';
describe('OAuthRegisteredClientsStore', () => {
// Create a mock implementation class for testing
class MockClientStore implements OAuthRegisteredClientsStore {
private clients: Record<string, OAuthClientInformationFull> = {};
async getClient(clientId: string): Promise<OAuthClientInformationFull | undefined> {
const client = this.clients[clientId];
// Return undefined for non-existent client
if (!client) return undefined;
// Check if client secret has expired
if (client.client_secret &&
client.client_secret_expires_at &&
client.client_secret_expires_at < Math.floor(Date.now() / 1000)) {
// If expired, retain client but remove the secret
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { client_secret, ...clientWithoutSecret } = client;
return clientWithoutSecret as OAuthClientInformationFull;
}
return client;
}
async registerClient(client: OAuthClientInformationFull): Promise<OAuthClientInformationFull> {
this.clients[client.client_id] = { ...client };
return client;
}
}
let mockStore: MockClientStore;
beforeEach(() => {
mockStore = new MockClientStore();
});
describe('getClient', () => {
it('returns undefined for non-existent client', async () => {
const result = await mockStore.getClient('non-existent-id');
expect(result).toBeUndefined();
});
it('returns client information for existing client', async () => {
const mockClient: OAuthClientInformationFull = {
client_id: 'test-client-123',
client_secret: 'secret456',
redirect_uris: ['https://example.com/callback']
};
await mockStore.registerClient(mockClient);
const result = await mockStore.getClient('test-client-123');
expect(result).toEqual(mockClient);
});
it('handles expired client secrets correctly', async () => {
const now = Math.floor(Date.now() / 1000);
// Client with expired secret (one hour in the past)
const expiredClient: OAuthClientInformationFull = {
client_id: 'expired-client',
client_secret: 'expired-secret',
client_secret_expires_at: now - 3600,
redirect_uris: ['https://example.com/callback']
};
await mockStore.registerClient(expiredClient);
const result = await mockStore.getClient('expired-client');
// Expect client to be returned but without the secret
expect(result).toBeDefined();
expect(result!.client_id).toBe('expired-client');
expect(result!.client_secret).toBeUndefined();
});
it('keeps valid client secrets', async () => {
const now = Math.floor(Date.now() / 1000);
// Client with valid secret (expires one hour in the future)
const validClient: OAuthClientInformationFull = {
client_id: 'valid-client',
client_secret: 'valid-secret',
client_secret_expires_at: now + 3600,
redirect_uris: ['https://example.com/callback']
};
await mockStore.registerClient(validClient);
const result = await mockStore.getClient('valid-client');
// Secret should still be present
expect(result?.client_secret).toBe('valid-secret');
});
});
describe('registerClient', () => {
it('successfully registers a new client', async () => {
const newClient: OAuthClientInformationFull = {
client_id: 'new-client-id',
client_secret: 'new-client-secret',
redirect_uris: ['https://example.com/callback']
};
const result = await mockStore.registerClient(newClient);
// Verify registration returns the client
expect(result).toEqual(newClient);
// Verify the client is retrievable
const storedClient = await mockStore.getClient('new-client-id');
expect(storedClient).toEqual(newClient);
});
it('handles clients with all metadata fields', async () => {
const fullClient: OAuthClientInformationFull = {
client_id: 'full-client',
client_secret: 'full-secret',
client_id_issued_at: Math.floor(Date.now() / 1000),
client_secret_expires_at: Math.floor(Date.now() / 1000) + 86400, // 24 hours
redirect_uris: ['https://example.com/callback'],
token_endpoint_auth_method: 'client_secret_basic',
grant_types: ['authorization_code', 'refresh_token'],
response_types: ['code'],
client_name: 'Test Client',
client_uri: 'https://example.com',
logo_uri: 'https://example.com/logo.png',
scope: 'profile email',
contacts: ['[email protected]'],
tos_uri: 'https://example.com/tos',
policy_uri: 'https://example.com/privacy',
jwks_uri: 'https://example.com/jwks',
software_id: 'test-software',
software_version: '1.0.0'
};
await mockStore.registerClient(fullClient);
const result = await mockStore.getClient('full-client');
expect(result).toEqual(fullClient);
});
});
});