Skip to content

Commit

Permalink
More validations, shorter logs
Browse files Browse the repository at this point in the history
  • Loading branch information
dcadenas committed Feb 20, 2024
1 parent cbd9858 commit 8a12650
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 28 deletions.
13 changes: 7 additions & 6 deletions config/test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
export default {
redis: {
db: 2,
},
logLevel: "fatal",
servicePubkey: '6c815df9b3e7f43492c232aba075b5fa5b6a60b731ce6ccfc7c1e8bd2adcceb2',
};
redis: {
db: 2,
},
logLevel: "fatal",
servicePubkey:
"6c815df9b3e7f43492c232aba075b5fa5b6a60b731ce6ccfc7c1e8bd2adcceb2",
};
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"nostr-tools": "^1.17.0",
"pino": "^8.17.1",
"pino-http": "^8.6.0",
"pino-pretty": "^10.3.0",
"prom-client": "^15.1.0"
},
"devDependencies": {
Expand Down
23 changes: 5 additions & 18 deletions src/logger.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,8 @@
import pino, { transport as _transport, stdTimeFunctions } from 'pino';
import config from '../config/index.js';

const transport = _transport({
targets: [
{
target: 'pino-pretty',
options: {
colorize: true,
minimumLevel: config.logLevel,
}
},
],
});
import pino from "pino";
import config from "../config/index.js";

export default pino({
level: config.logLevel,
timestamp: stdTimeFunctions.isoTime,
},
transport
);
timestamp: pino.stdTimeFunctions.isoTime,
prettyPrint: false, // Ensuring logs are in JSON format, single-line
});
24 changes: 22 additions & 2 deletions src/middlewares/extractNip05Name.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,31 @@ function extractName(req) {
const nameFromQueryOrBody =
req.query.name || req.params.name || req.body.name;

let name = nameFromQueryOrBody;
if (nameFromQueryOrBody === "_") {
return validateAndReturnSubdomain(nonRootSubdomains);
name = validateAndReturnSubdomain(nonRootSubdomains);
}

return nameFromQueryOrBody;
validateName(name);

return name;
}

function validateName(name) {
if (name.length < 3) {
throw new AppError(
422,
`Name '${name}' should have more than 3 characters.`
);
}

if (name.startsWith("-")) {
throw new AppError(422, `Name '${name}' should not start with a hyphen.`);
}

if (name.endsWith("-")) {
throw new AppError(422, `Name '${name}' should not start with a hyphen.`);
}
}

function validateDomain(host) {
Expand Down
2 changes: 1 addition & 1 deletion src/schemas.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const pubkeyPattern = "^[a-fA-F0-9]{64}$";
// We accept uppercase but we will convert everything to lowercase
const namePattern = "^[a-zA-Z0-9-_.]+$";
const namePattern = "^[a-zA-Z0-9-_]+$";
const maxLength = 30;

export const postNip05 = {
Expand Down
44 changes: 44 additions & 0 deletions test/app.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,50 @@ describe("Nostr NIP 05 API tests", () => {
.expect(422);
});

it("should fail if the name is too short", async () => {
const userData = createUserData({ name: "a" });

await request(app)
.post("/api/names")
.set("Host", "nos.social")
.set("Authorization", `Nostr ${nip98PostAuthToken}`)
.send(userData)
.expect(422);
});

it("should fail if the name starts with -", async () => {
const userData = createUserData({ name: "-aa" });

await request(app)
.post("/api/names")
.set("Host", "nos.social")
.set("Authorization", `Nostr ${nip98PostAuthToken}`)
.send(userData)
.expect(422);
});

it("should fail if the name ends with -", async () => {
const userData = createUserData({ name: "aa-" });

await request(app)
.post("/api/names")
.set("Host", "nos.social")
.set("Authorization", `Nostr ${nip98PostAuthToken}`)
.send(userData)
.expect(422);
});

it("should fail if the name includes a dot", async () => {
const userData = createUserData({ name: "aa." });

await request(app)
.post("/api/names")
.set("Host", "nos.social")
.set("Authorization", `Nostr ${nip98PostAuthToken}`)
.send(userData)
.expect(422);
});

it("should fail if the name is not found", async () => {
await request(app)
.get("/.well-known/nostr.json")
Expand Down

0 comments on commit 8a12650

Please sign in to comment.