Skip to content

Commit 4b64982

Browse files
committed
[FIX] added fixes for account expired
1 parent ebee8c4 commit 4b64982

File tree

6 files changed

+74
-25
lines changed

6 files changed

+74
-25
lines changed

nats-base-client/core.ts

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

9394
export function isNatsError(err: NatsError | Error): err is NatsError {
@@ -170,7 +171,8 @@ export class NatsError extends Error {
170171

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

176178
isAuthTimeout(): boolean {

nats-base-client/deno.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@nats-io/nats-core",
3-
"version": "3.0.0-14",
3+
"version": "3.0.0-15",
44
"exports": {
55
".": "./mod.ts",
66
"./internal": "./internal_mod.ts"

nats-base-client/protocol.ts

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,7 @@ export class Subscriptions {
340340
sub = subs.find((s) => {
341341
return s.subject === ctx.subject && s.queue === ctx.queue;
342342
});
343-
}
344-
if (ctx.operation === "publish") {
343+
} else if (ctx.operation === "publish") {
345344
// we have a no mux subscription
346345
sub = subs.find((s) => {
347346
return s.requestSubject === ctx.subject;
@@ -693,22 +692,29 @@ export class ProtocolHandler implements Dispatcher<ParserEvent> {
693692
const err = new NatsError(s, ErrorCode.PermissionsViolation);
694693
const m = s.match(/(Publish|Subscription) to "(\S+)"/);
695694
if (m) {
695+
const operation = m[1].toLowerCase();
696+
const subject = m[2];
697+
let queue = undefined;
698+
699+
if (operation === "subscription") {
700+
const qm = s.match(/using queue "(\S+)"/);
701+
if (qm) {
702+
queue = qm[1];
703+
}
704+
}
696705
err.permissionContext = {
697-
operation: m[1].toLowerCase(),
698-
subject: m[2],
699-
queue: undefined,
706+
operation,
707+
subject,
708+
queue,
700709
};
701-
702-
const qm = s.match(/using queue "(\S+)"/);
703-
if (qm) {
704-
err.permissionContext.queue = qm[1];
705-
}
706710
}
707711
return err;
708712
} else if (t.indexOf("authorization violation") !== -1) {
709713
return new NatsError(s, ErrorCode.AuthorizationViolation);
710714
} else if (t.indexOf("user authentication expired") !== -1) {
711715
return new NatsError(s, ErrorCode.AuthenticationExpired);
716+
} else if (t.indexOf("account authentication expired") != -1) {
717+
return new NatsError(s, ErrorCode.AccountExpired);
712718
} else if (t.indexOf("authentication timeout") !== -1) {
713719
return new NatsError(s, ErrorCode.AuthenticationTimeout);
714720
} else {

nats-base-client/tests/auth_test.ts

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import {
2222
assert,
2323
assertArrayIncludes,
2424
assertEquals,
25+
assertExists,
2526
assertRejects,
2627
assertStringIncludes,
2728
fail,
@@ -32,7 +33,7 @@ import {
3233
encodeOperator,
3334
encodeUser,
3435
} from "jsr:@nats-io/[email protected]";
35-
import type {
36+
import {
3637
MsgImpl,
3738
NatsConnection,
3839
NatsConnectionImpl,
@@ -1259,27 +1260,23 @@ Deno.test("auth - request context", async () => {
12591260
await cleanup(ns, nc, a);
12601261
});
12611262

1262-
Deno.test("auth - sub permission reload", async () => {
1263+
Deno.test("auth - sub queue permission", async () => {
12631264
const conf = {
12641265
authorization: {
12651266
users: [{
12661267
user: "a",
12671268
password: "a",
1268-
permissions: { subscribe: ["q A", "h"] },
1269+
permissions: { subscribe: ["q A"] },
12691270
}],
12701271
},
12711272
};
12721273

1273-
const { ns, nc } = await _setup(connect, conf, {
1274-
user: "a",
1275-
pass: "a",
1276-
debug: true,
1277-
});
1274+
const { ns, nc } = await _setup(connect, conf, { user: "a", pass: "a" });
12781275

12791276
const qA = deferred();
12801277
nc.subscribe("q", {
12811278
queue: "A",
1282-
callback: (err, msg) => {
1279+
callback: (err, _msg) => {
12831280
if (err) {
12841281
qA.reject(err);
12851282
}
@@ -1289,7 +1286,7 @@ Deno.test("auth - sub permission reload", async () => {
12891286
const qBad = deferred<NatsError>();
12901287
nc.subscribe("q", {
12911288
queue: "bad",
1292-
callback: (err, msg) => {
1289+
callback: (err, _msg) => {
12931290
if (err) {
12941291
qBad.resolve(err);
12951292
}
@@ -1306,3 +1303,47 @@ Deno.test("auth - sub permission reload", async () => {
13061303
assertStringIncludes(err.message, 'using queue "bad"');
13071304
await cleanup(ns, nc);
13081305
});
1306+
1307+
Deno.test("auth - account expired", async () => {
1308+
const O = nkeys.createOperator();
1309+
const A = nkeys.createAccount();
1310+
1311+
const resolver: Record<string, string> = {};
1312+
resolver[A.getPublicKey()] = await encodeAccount("A", A, {
1313+
limits: {
1314+
conn: -1,
1315+
subs: -1,
1316+
},
1317+
}, { signer: O, exp: Math.round(Date.now() / 1000) + 3 });
1318+
1319+
const conf = {
1320+
operator: await encodeOperator("O", O),
1321+
resolver: "MEMORY",
1322+
"resolver_preload": resolver,
1323+
};
1324+
1325+
const U = nkeys.createUser();
1326+
const ujwt = await encodeUser("U", U, A, { bearer_token: true });
1327+
1328+
const { ns, nc } = await _setup(connect, conf, {
1329+
debug: true,
1330+
reconnect: false,
1331+
authenticator: jwtAuthenticator(ujwt),
1332+
});
1333+
1334+
const d = deferred();
1335+
(async () => {
1336+
for await (const s of nc.status()) {
1337+
if (s.type === Events.Error && s.data === ErrorCode.AccountExpired) {
1338+
d.resolve();
1339+
break;
1340+
}
1341+
}
1342+
})().catch(() => {});
1343+
1344+
const w = await nc.closed();
1345+
assertExists(w);
1346+
assertEquals((w as NatsError).code, ErrorCode.AccountExpired);
1347+
1348+
await cleanup(ns, nc);
1349+
});

nats-base-client/tests/connect.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export { connect } from "jsr:@nats-io/[email protected]2";
1+
export { connect } from "jsr:@nats-io/[email protected]4";

nats-base-client/tsconfig.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
"sourceMap": true,
88
"declaration": true,
99
"allowJs": true,
10-
"removeComments": false,
10+
"removeComments": false
1111
},
1212
"include": [
1313
"cjs/**/*"
1414
]
15-
}
15+
}

0 commit comments

Comments
 (0)