Skip to content

Commit bb15a92

Browse files
committed
chore: added expiry to jwt
1 parent 01f7596 commit bb15a92

File tree

9 files changed

+73
-74
lines changed

9 files changed

+73
-74
lines changed
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import type { HandlerTypes } from '@matrixai/rpc';
2+
import type AuthIdentityToken from '../handlers/AuthIdentityToken.js';
3+
import { UnaryCaller } from '@matrixai/rpc';
4+
5+
type CallerTypes = HandlerTypes<AuthIdentityToken>;
6+
7+
const authIdentityToken = new UnaryCaller<
8+
CallerTypes['input'],
9+
CallerTypes['output']
10+
>();
11+
12+
export default authIdentityToken;

src/client/callers/authSignToken.ts

Lines changed: 0 additions & 12 deletions
This file was deleted.

src/client/callers/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import agentStop from './agentStop.js';
44
import agentUnlock from './agentUnlock.js';
55
import auditEventsGet from './auditEventsGet.js';
66
import auditMetricGet from './auditMetricGet.js';
7-
import authSignToken from './authSignToken.js';
7+
import authIdentityToken from './authIdentityToken.js';
88
import gestaltsActionsGetByIdentity from './gestaltsActionsGetByIdentity.js';
99
import gestaltsActionsGetByNode from './gestaltsActionsGetByNode.js';
1010
import gestaltsActionsSetByIdentity from './gestaltsActionsSetByIdentity.js';
@@ -86,7 +86,7 @@ const clientManifest = {
8686
agentUnlock,
8787
auditEventsGet,
8888
auditMetricGet,
89-
authSignToken,
89+
authIdentityToken,
9090
gestaltsActionsGetByIdentity,
9191
gestaltsActionsGetByNode,
9292
gestaltsActionsSetByIdentity,
@@ -167,7 +167,7 @@ export {
167167
agentStop,
168168
agentUnlock,
169169
auditEventsGet,
170-
authSignToken,
170+
authIdentityToken,
171171
gestaltsActionsGetByIdentity,
172172
gestaltsActionsGetByNode,
173173
gestaltsActionsSetByIdentity,

src/client/errors.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ class ErrorClientProtocolError<T> extends ErrorClient<T> {
2828
exitCode = sysexits.USAGE;
2929
}
3030

31+
class ErrorClientAuthenticationInvalidJTI<T> extends ErrorClient<T> {
32+
static description = 'Failed to generate JTI';
33+
exitCode = sysexits.PROTOCOL;
34+
}
35+
3136
class ErrorClientService<T> extends ErrorClient<T> {}
3237

3338
class ErrorClientServiceRunning<T> extends ErrorClientService<T> {
@@ -50,22 +55,17 @@ class ErrorClientVerificationFailed<T> extends ErrorClientService<T> {
5055
exitCode = sysexits.USAGE;
5156
}
5257

53-
class ErrorClientAuthenticationInvalidToken<T> extends ErrorClient<T> {
54-
static description = 'Token is invalid';
55-
exitCode = sysexits.PROTOCOL;
56-
}
57-
5858
export {
5959
ErrorClient,
6060
ErrorClientAuthMissing,
6161
ErrorClientAuthFormat,
6262
ErrorClientAuthDenied,
6363
ErrorClientInvalidHeader,
6464
ErrorClientProtocolError,
65+
ErrorClientAuthenticationInvalidJTI,
6566
ErrorClientService,
6667
ErrorClientServiceRunning,
6768
ErrorClientServiceNotRunning,
6869
ErrorClientServiceDestroyed,
6970
ErrorClientVerificationFailed,
70-
ErrorClientAuthenticationInvalidToken,
7171
};
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import type {
2+
ClientRPCRequestParams,
3+
ClientRPCResponseResult,
4+
} from '../types.js';
5+
import type { SignedTokenEncoded, TokenPayload } from '../../tokens/types.js';
6+
import type KeyRing from '../../keys/KeyRing.js';
7+
import { IdSortable } from '@matrixai/id';
8+
import { UnaryHandler } from '@matrixai/rpc';
9+
import Token from '../../tokens/Token.js';
10+
import * as nodesUtils from '../../nodes/utils.js';
11+
import * as clientErrors from '../errors.js';
12+
13+
class AuthIdentityToken extends UnaryHandler<
14+
{
15+
keyRing: KeyRing;
16+
},
17+
ClientRPCRequestParams,
18+
ClientRPCResponseResult<SignedTokenEncoded>
19+
> {
20+
public handle = async (): Promise<SignedTokenEncoded> => {
21+
const { keyRing }: { keyRing: KeyRing } = this.container;
22+
const idGen = new IdSortable();
23+
const jti = idGen.next().value;
24+
if (jti == null) {
25+
throw new clientErrors.ErrorClientAuthenticationInvalidJTI();
26+
}
27+
const outgoingToken = Token.fromPayload<TokenPayload>({
28+
jti: jti.toMultibase('base64'),
29+
exp: Math.floor(Date.now() / 1000) + 60, // 60 seconds after issuing
30+
iss: nodesUtils.encodeNodeId(keyRing.getNodeId()),
31+
});
32+
outgoingToken.signWithPrivateKey(keyRing.keyPair);
33+
return outgoingToken.toEncoded();
34+
};
35+
}
36+
37+
export default AuthIdentityToken;

src/client/handlers/AuthSignToken.ts

Lines changed: 0 additions & 30 deletions
This file was deleted.

src/client/handlers/index.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import AgentStop from './AgentStop.js';
2222
import AgentUnlock from './AgentUnlock.js';
2323
import AuditEventsGet from './AuditEventsGet.js';
2424
import AuditMetricGet from './AuditMetricGet.js';
25-
import AuthSignToken from './AuthSignToken.js';
25+
import AuthIdentityToken from './AuthIdentityToken.js';
2626
import GestaltsActionsGetByIdentity from './GestaltsActionsGetByIdentity.js';
2727
import GestaltsActionsGetByNode from './GestaltsActionsGetByNode.js';
2828
import GestaltsActionsSetByIdentity from './GestaltsActionsSetByIdentity.js';
@@ -123,7 +123,7 @@ const serverManifest = (container: {
123123
agentUnlock: new AgentUnlock(container),
124124
auditEventsGet: new AuditEventsGet(container),
125125
auditMetricGet: new AuditMetricGet(container),
126-
authSignToken: new AuthSignToken(container),
126+
authSignToken: new AuthIdentityToken(container),
127127
gestaltsActionsGetByIdentity: new GestaltsActionsGetByIdentity(container),
128128
gestaltsActionsGetByNode: new GestaltsActionsGetByNode(container),
129129
gestaltsActionsSetByIdentity: new GestaltsActionsSetByIdentity(container),
@@ -210,7 +210,7 @@ export {
210210
AgentUnlock,
211211
AuditEventsGet,
212212
AuditMetricGet,
213-
AuthSignToken,
213+
AuthIdentityToken,
214214
GestaltsActionsGetByIdentity,
215215
GestaltsActionsGetByNode,
216216
GestaltsActionsSetByIdentity,

src/client/types.ts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import type {
2121
} from '../keys/types.js';
2222
import type { Notification } from '../notifications/types.js';
2323
import type { ProviderToken } from '../identities/types.js';
24-
import type { TokenPayload, SignedTokenEncoded } from '../tokens/types.js';
2524
import type { AuditMetricGetTypeOverride } from './callers/auditMetricGet.js';
2625
import type {
2726
NodeContact,
@@ -108,12 +107,6 @@ type TokenMessage = {
108107
token: ProviderToken;
109108
};
110109

111-
type IdentityResponseData = TokenPayload & {
112-
nodeId: NodeIdEncoded;
113-
};
114-
115-
type TokenIdentityResponse = SignedTokenEncoded;
116-
117110
// Nodes messages
118111

119112
type NodeIdMessage = {
@@ -412,8 +405,6 @@ export type {
412405
ClaimIdMessage,
413406
ClaimNodeMessage,
414407
TokenMessage,
415-
IdentityResponseData,
416-
TokenIdentityResponse,
417408
NodeIdMessage,
418409
AddressMessage,
419410
NodeAddressMessage,

tests/client/handlers/auth.test.ts

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import type { IdentityResponseData } from '#src/client/types.js';
21
import type { TLSConfig } from '#network/types.js';
32
import fs from 'node:fs';
43
import path from 'node:path';
@@ -7,17 +6,17 @@ import Logger, { formatting, LogLevel, StreamHandler } from '@matrixai/logger';
76
import { RPCClient } from '@matrixai/rpc';
87
import { WebSocketClient } from '@matrixai/ws';
98
import * as testsUtils from '../../utils/index.js';
10-
import { AuthSignToken } from '#client/handlers/index.js';
11-
import { authSignToken } from '#client/callers/index.js';
9+
import { AuthIdentityToken } from '#client/handlers/index.js';
10+
import { authIdentityToken } from '#client/callers/index.js';
1211
import KeyRing from '#keys/KeyRing.js';
1312
import Token from '#tokens/Token.js';
1413
import ClientService from '#client/ClientService.js';
1514
import * as keysUtils from '#keys/utils/index.js';
1615
import * as networkUtils from '#network/utils.js';
1716
import * as nodesUtils from '#nodes/utils.js';
1817

19-
describe('authSignToken', () => {
20-
const logger = new Logger('authSignToken test', LogLevel.WARN, [
18+
describe('authIdentityToken', () => {
19+
const logger = new Logger('authIdentityToken test', LogLevel.WARN, [
2120
new StreamHandler(
2221
formatting.format`${formatting.level}:${formatting.keys}:${formatting.msg}`,
2322
),
@@ -30,7 +29,7 @@ describe('authSignToken', () => {
3029
let clientService: ClientService;
3130
let webSocketClient: WebSocketClient;
3231
let rpcClient: RPCClient<{
33-
authSignToken: typeof authSignToken;
32+
authIdentityToken: typeof authIdentityToken;
3433
}>;
3534

3635
beforeEach(async () => {
@@ -53,7 +52,7 @@ describe('authSignToken', () => {
5352
});
5453
await clientService.start({
5554
manifest: {
56-
authSignToken: new AuthSignToken({
55+
authIdentityToken: new AuthIdentityToken({
5756
keyRing,
5857
}),
5958
},
@@ -69,7 +68,7 @@ describe('authSignToken', () => {
6968
});
7069
rpcClient = new RPCClient({
7170
manifest: {
72-
authSignToken,
71+
authIdentityToken,
7372
},
7473
streamFactory: () => webSocketClient.connection.newStream(),
7574
toError: networkUtils.toError,
@@ -89,11 +88,13 @@ describe('authSignToken', () => {
8988
});
9089

9190
test('should return a signed token', async () => {
92-
const identityToken = await rpcClient.methods.authSignToken({});
93-
const decodedToken = Token.fromEncoded<IdentityResponseData>(identityToken);
91+
const identityToken = await rpcClient.methods.authIdentityToken({});
92+
const decodedToken = Token.fromEncoded(identityToken);
9493
const decodedPublicKey = keysUtils.publicKeyFromNodeId(keyRing.getNodeId());
9594
expect(decodedToken.verifyWithPublicKey(decodedPublicKey)).toBeTrue();
9695
const encodedNodeId = nodesUtils.encodeNodeId(keyRing.getNodeId());
97-
expect(decodedToken.payload.nodeId).toBe(encodedNodeId);
96+
expect(decodedToken.payload.iss).toBe(encodedNodeId);
97+
expect(decodedToken.payload.exp).toBeDefined();
98+
expect(decodedToken.payload.jti).toBeDefined();
9899
});
99100
});

0 commit comments

Comments
 (0)