refactor(api): 🎨 Don't use node:crypto for random strings

This commit is contained in:
Jesse Wierzbinski 2024-06-12 19:38:26 -10:00
parent d8cb1d475b
commit d301d4da09
No known key found for this signature in database
12 changed files with 37 additions and 35 deletions

View file

@ -59,6 +59,6 @@
"ignore": ["node_modules", "dist", "glitch", "glitch-dev"]
},
"javascript": {
"globals": ["Bun", "HTMLRewriter"]
"globals": ["Bun", "HTMLRewriter", "BufferEncoding"]
}
}

View file

@ -1,6 +1,6 @@
import { randomBytes } from "node:crypto";
import { idValidator } from "@/api";
import { getBestContentType, urlToContentFormat } from "@/content_types";
import { randomString } from "@/math";
import { addUserToMeilisearch } from "@/meilisearch";
import { proxyUrl } from "@/response";
import { EntityValidator } from "@lysand-org/federation";
@ -190,7 +190,7 @@ export class User extends BaseInterface<typeof Users, UserWithRelations> {
}
async resetPassword() {
const resetToken = await randomBytes(32).toString("hex");
const resetToken = randomString(32, "hex");
await this.update({
passwordResetToken: resetToken,

View file

@ -1,5 +1,5 @@
import { afterAll, describe, expect, test } from "bun:test";
import { randomBytes } from "node:crypto";
import { randomString } from "@/math";
import { eq } from "drizzle-orm";
import { db } from "~/drizzle/db";
import { Applications } from "~/drizzle/schema";
@ -15,7 +15,7 @@ const application = (
.insert(Applications)
.values({
name: "Test Application",
clientId: randomBytes(32).toString("hex"),
clientId: randomString(32, "hex"),
secret: "test",
redirectUri: "https://example.com",
scopes: "read write",

View file

@ -1,5 +1,5 @@
import { randomBytes } from "node:crypto";
import { applyConfig, handleZodError } from "@/api";
import { randomString } from "@/math";
import { response } from "@/response";
import { zValidator } from "@hono/zod-validator";
import { eq } from "drizzle-orm";
@ -81,8 +81,8 @@ export default (app: Hono) =>
});
}
const code = randomBytes(32).toString("hex");
const accessToken = randomBytes(64).toString("base64url");
const code = randomString(32, "hex");
const accessToken = randomString(64, "base64url");
await db.insert(Tokens).values({
accessToken,

View file

@ -1,5 +1,5 @@
import { afterAll, describe, expect, test } from "bun:test";
import { randomBytes } from "node:crypto";
import { randomString } from "@/math";
import { eq } from "drizzle-orm";
import { db } from "~/drizzle/db";
import { Applications } from "~/drizzle/schema";
@ -8,8 +8,8 @@ import { getTestUsers, sendTestRequest } from "~/tests/utils";
import { meta } from "./index";
const { users, deleteUsers, passwords } = await getTestUsers(1);
const token = randomBytes(32).toString("hex");
const newPassword = randomBytes(16).toString("hex");
const token = randomString(32, "hex");
const newPassword = randomString(16, "hex");
// Create application
const application = (
@ -17,7 +17,7 @@ const application = (
.insert(Applications)
.values({
name: "Test Application",
clientId: randomBytes(32).toString("hex"),
clientId: randomString(32, "hex"),
secret: "test",
redirectUri: "https://example.com",
scopes: "read write",

View file

@ -1,5 +1,5 @@
import { afterEach, describe, expect, test } from "bun:test";
import { randomBytes } from "node:crypto";
import { randomString } from "@/math";
import { config } from "config-manager";
import { eq } from "drizzle-orm";
import { db } from "~/drizzle/db";
@ -7,8 +7,8 @@ import { Users } from "~/drizzle/schema";
import { sendTestRequest } from "~/tests/utils";
import { meta } from "./index";
const username = randomBytes(10).toString("hex");
const username2 = randomBytes(10).toString("hex");
const username = randomString(10, "hex");
const username2 = randomString(10, "hex");
afterEach(async () => {
await db.delete(Users).where(eq(Users.username, username));

View file

@ -1,5 +1,5 @@
import { randomBytes } from "node:crypto";
import { applyConfig, handleZodError, jsonOrForm } from "@/api";
import { randomString } from "@/math";
import { jsonResponse } from "@/response";
import { zValidator } from "@hono/zod-validator";
import type { Hono } from "hono";
@ -54,8 +54,8 @@ export default (app: Hono) =>
redirectUri: decodeURIComponent(redirect_uris) || "",
scopes: scopes || "read",
website: website || null,
clientId: randomBytes(32).toString("base64url"),
secret: randomBytes(64).toString("base64url"),
clientId: randomString(32, "base64url"),
secret: randomString(64, "base64url"),
})
.returning()
)[0];

View file

@ -1,6 +1,6 @@
import { randomBytes } from "node:crypto";
import { applyConfig, auth, handleZodError, jsonOrForm } from "@/api";
import { oauthRedirectUri } from "@/constants";
import { randomString } from "@/math";
import { errorResponse, jsonResponse } from "@/response";
import { zValidator } from "@hono/zod-validator";
import type { Hono } from "hono";
@ -134,9 +134,7 @@ export default (app: Hono) =>
await db
.insert(Applications)
.values({
clientId:
user.id +
randomBytes(32).toString("base64url"),
clientId: user.id + randomString(32, "base64"),
name: "Lysand",
redirectUri: `${oauthRedirectUri(issuerId)}`,
scopes: "openid profile email",

View file

@ -1,5 +1,5 @@
import { randomBytes } from "node:crypto";
import { applyConfig, handleZodError, jsonOrForm } from "@/api";
import { randomString } from "@/math";
import { response } from "@/response";
import { zValidator } from "@hono/zod-validator";
import type { Hono } from "hono";
@ -240,7 +240,7 @@ export default (app: Hono) =>
}
// Generate tokens
const code = randomBytes(256).toString("base64url");
const code = randomString(256, "base64url");
// Handle the requested scopes
let idTokenPayload = {};
@ -287,7 +287,7 @@ export default (app: Hono) =>
.sign(privateKey);
await db.insert(Tokens).values({
accessToken: randomBytes(64).toString("base64url"),
accessToken: randomString(64, "base64url"),
code: code,
scope: scope ?? application.scopes,
tokenType: TokenType.Bearer,

View file

@ -1,5 +1,5 @@
import { randomBytes } from "node:crypto";
import { applyConfig, handleZodError } from "@/api";
import { randomString } from "@/math";
import { errorResponse, response } from "@/response";
import { zValidator } from "@hono/zod-validator";
import type { Hono } from "hono";
@ -174,10 +174,10 @@ export default (app: Hono) =>
return errorResponse("Application not found", 500);
}
const code = randomBytes(32).toString("hex");
const code = randomString(32, "hex");
await db.insert(Tokens).values({
accessToken: randomBytes(64).toString("base64url"),
accessToken: randomString(64, "base64url"),
code: code,
scope: flow.application.scopes,
tokenType: TokenType.Bearer,

View file

@ -1,5 +1,5 @@
import { randomBytes } from "node:crypto";
import { consoleLogger } from "@/loggers";
import { randomString } from "@/math";
import { asc, inArray, like } from "drizzle-orm";
import type { Status } from "~/database/entities/status";
import { db } from "~/drizzle/db";
@ -35,11 +35,11 @@ export const getTestUsers = async (count: number) => {
const passwords: string[] = [];
for (let i = 0; i < count; i++) {
const password = randomBytes(32).toString("hex");
const password = randomString(32, "hex");
const user = await User.fromDataLocal({
username: `test-${randomBytes(32).toString("hex")}`,
email: `${randomBytes(32).toString("hex")}@test.com`,
username: `test-${randomString(32, "hex")}`,
email: `${randomString(32, "hex")}@test.com`,
password,
});
@ -55,11 +55,11 @@ export const getTestUsers = async (count: number) => {
.insert(Tokens)
.values(
users.map((u) => ({
accessToken: randomBytes(32).toString("hex"),
accessToken: randomString(32, "hex"),
tokenType: "bearer",
userId: u.id,
applicationId: null,
code: randomBytes(32).toString("hex"),
code: randomString(32, "hex"),
scope: "read write follow push",
})),
)
@ -89,7 +89,7 @@ export const getTestStatuses = async (
for (let i = 0; i < count; i++) {
const newStatus = await Note.insert({
content: `${i} ${randomBytes(32).toString("hex")}`,
content: `${i} ${randomString(32, "hex")}`,
authorId: user.id,
sensitive: false,
updatedAt: new Date().toISOString(),

4
utils/math.ts Normal file
View file

@ -0,0 +1,4 @@
export const randomString = (length: number, encoding?: BufferEncoding) =>
Buffer.from(crypto.getRandomValues(new Uint8Array(length))).toString(
encoding,
);