Skip to content

Commit 9aa56fb

Browse files
committed
[FIX] account expired protocol message was not notified properly
1 parent 7661902 commit 9aa56fb

File tree

3 files changed

+49
-1
lines changed

3 files changed

+49
-1
lines changed

nats-base-client/core.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export enum ErrorCode {
8989
ProtocolError = "NATS_PROTOCOL_ERR",
9090
PermissionsViolation = "PERMISSIONS_VIOLATION",
9191
AuthenticationTimeout = "AUTHENTICATION_TIMEOUT",
92+
AccountExpired = "ACCOUNT_EXPIRED",
9293
}
9394

9495
export function isNatsError(err: NatsError | Error): err is NatsError {
@@ -171,7 +172,8 @@ export class NatsError extends Error {
171172

172173
isAuthError(): boolean {
173174
return this.code === ErrorCode.AuthenticationExpired ||
174-
this.code === ErrorCode.AuthorizationViolation;
175+
this.code === ErrorCode.AuthorizationViolation ||
176+
this.code === ErrorCode.AccountExpired;
175177
}
176178

177179
isAuthTimeout(): boolean {

nats-base-client/protocol.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,8 @@ export class ProtocolHandler implements Dispatcher<ParserEvent> {
713713
return new NatsError(s, ErrorCode.AuthorizationViolation);
714714
} else if (t.indexOf("user authentication expired") !== -1) {
715715
return new NatsError(s, ErrorCode.AuthenticationExpired);
716+
} else if (t.indexOf("account authentication expired") != -1) {
717+
return new NatsError(s, ErrorCode.AccountExpired);
716718
} else if (t.indexOf("authentication timeout") !== -1) {
717719
return new NatsError(s, ErrorCode.AuthenticationTimeout);
718720
} else {

tests/auth_test.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import {
1717
assertArrayIncludes,
1818
assertEquals,
19+
assertExists,
1920
assertRejects,
2021
assertStringIncludes,
2122
fail,
@@ -1299,3 +1300,46 @@ Deno.test("auth - sub permission queue", async () => {
12991300
assertStringIncludes(err.message, 'using queue "bad"');
13001301
await cleanup(ns, nc);
13011302
});
1303+
1304+
Deno.test("auth - account expired", async () => {
1305+
const O = nkeys.createOperator();
1306+
const A = nkeys.createAccount();
1307+
1308+
const resolver: Record<string, string> = {};
1309+
resolver[A.getPublicKey()] = await encodeAccount("A", A, {
1310+
limits: {
1311+
conn: -1,
1312+
subs: -1,
1313+
},
1314+
}, { signer: O, exp: Math.round(Date.now() / 1000) + 3 });
1315+
1316+
const conf = {
1317+
operator: await encodeOperator("O", O),
1318+
resolver: "MEMORY",
1319+
"resolver_preload": resolver,
1320+
};
1321+
1322+
const U = nkeys.createUser();
1323+
const ujwt = await encodeUser("U", U, A, { bearer_token: true });
1324+
1325+
const { ns, nc } = await setup(conf, {
1326+
reconnect: false,
1327+
authenticator: jwtAuthenticator(ujwt),
1328+
});
1329+
1330+
const d = deferred();
1331+
(async () => {
1332+
for await (const s of nc.status()) {
1333+
if (s.type === Events.Error && s.data === ErrorCode.AccountExpired) {
1334+
d.resolve();
1335+
break;
1336+
}
1337+
}
1338+
})().catch(() => {});
1339+
1340+
const w = await nc.closed();
1341+
assertExists(w);
1342+
assertEquals((w as NatsError).code, ErrorCode.AccountExpired);
1343+
1344+
await cleanup(ns, nc);
1345+
});

0 commit comments

Comments
 (0)