feat: add async suffix eslint rule (#485)
This commit is contained in:
@@ -128,7 +128,7 @@ export const boardRouter = createTRPCRouter({
|
||||
"full-access",
|
||||
);
|
||||
|
||||
await noBoardWithSimilarName(ctx.db, input.name, [input.id]);
|
||||
await noBoardWithSimilarNameAsync(ctx.db, input.name, [input.id]);
|
||||
|
||||
await ctx.db
|
||||
.update(boards)
|
||||
@@ -164,7 +164,7 @@ export const boardRouter = createTRPCRouter({
|
||||
const boardWhere = eq(boards.name, "default");
|
||||
await throwIfActionForbiddenAsync(ctx, boardWhere, "board-view");
|
||||
|
||||
return await getFullBoardWithWhere(
|
||||
return await getFullBoardWithWhereAsync(
|
||||
ctx.db,
|
||||
boardWhere,
|
||||
ctx.session?.user.id ?? null,
|
||||
@@ -176,7 +176,7 @@ export const boardRouter = createTRPCRouter({
|
||||
const boardWhere = eq(boards.name, input.name);
|
||||
await throwIfActionForbiddenAsync(ctx, boardWhere, "board-view");
|
||||
|
||||
return await getFullBoardWithWhere(
|
||||
return await getFullBoardWithWhereAsync(
|
||||
ctx.db,
|
||||
boardWhere,
|
||||
ctx.session?.user.id ?? null,
|
||||
@@ -229,7 +229,7 @@ export const boardRouter = createTRPCRouter({
|
||||
);
|
||||
|
||||
await ctx.db.transaction(async (transaction) => {
|
||||
const dbBoard = await getFullBoardWithWhere(
|
||||
const dbBoard = await getFullBoardWithWhereAsync(
|
||||
transaction,
|
||||
eq(boards.id, input.id),
|
||||
ctx.session.user.id,
|
||||
@@ -523,7 +523,7 @@ export const boardRouter = createTRPCRouter({
|
||||
}),
|
||||
});
|
||||
|
||||
const noBoardWithSimilarName = async (
|
||||
const noBoardWithSimilarNameAsync = async (
|
||||
db: Database,
|
||||
name: string,
|
||||
ignoredIds: string[] = [],
|
||||
@@ -549,7 +549,7 @@ const noBoardWithSimilarName = async (
|
||||
}
|
||||
};
|
||||
|
||||
const getFullBoardWithWhere = async (
|
||||
const getFullBoardWithWhereAsync = async (
|
||||
db: Database,
|
||||
where: SQL<unknown>,
|
||||
userId: string | null,
|
||||
|
||||
@@ -106,7 +106,7 @@ export const groupRouter = createTRPCRouter({
|
||||
.input(validation.group.create)
|
||||
.mutation(async ({ input, ctx }) => {
|
||||
const normalizedName = normalizeName(input.name);
|
||||
await checkSimilarNameAndThrow(ctx.db, normalizedName);
|
||||
await checkSimilarNameAndThrowAsync(ctx.db, normalizedName);
|
||||
|
||||
const id = createId();
|
||||
await ctx.db.insert(groups).values({
|
||||
@@ -123,7 +123,7 @@ export const groupRouter = createTRPCRouter({
|
||||
await throwIfGroupNotFoundAsync(ctx.db, input.id);
|
||||
|
||||
const normalizedName = normalizeName(input.name);
|
||||
await checkSimilarNameAndThrow(ctx.db, normalizedName, input.id);
|
||||
await checkSimilarNameAndThrowAsync(ctx.db, normalizedName, input.id);
|
||||
|
||||
await ctx.db
|
||||
.update(groups)
|
||||
@@ -206,7 +206,7 @@ export const groupRouter = createTRPCRouter({
|
||||
|
||||
const normalizeName = (name: string) => name.trim();
|
||||
|
||||
const checkSimilarNameAndThrow = async (
|
||||
const checkSimilarNameAndThrowAsync = async (
|
||||
db: Database,
|
||||
name: string,
|
||||
ignoreId?: string,
|
||||
|
||||
@@ -139,9 +139,9 @@ export const integrationRouter = createTRPCRouter({
|
||||
(secret) => secret.kind === changedSecret.kind,
|
||||
)
|
||||
) {
|
||||
await addSecret(ctx.db, secretInput);
|
||||
await addSecretAsync(ctx.db, secretInput);
|
||||
} else {
|
||||
await updateSecret(ctx.db, secretInput);
|
||||
await updateSecretAsync(ctx.db, secretInput);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -276,7 +276,7 @@ interface UpdateSecretInput {
|
||||
value: string;
|
||||
kind: IntegrationSecretKind;
|
||||
}
|
||||
const updateSecret = async (db: Database, input: UpdateSecretInput) => {
|
||||
const updateSecretAsync = async (db: Database, input: UpdateSecretInput) => {
|
||||
await db
|
||||
.update(integrationSecrets)
|
||||
.set({
|
||||
@@ -296,7 +296,7 @@ interface AddSecretInput {
|
||||
value: string;
|
||||
kind: IntegrationSecretKind;
|
||||
}
|
||||
const addSecret = async (db: Database, input: AddSecretInput) => {
|
||||
const addSecretAsync = async (db: Database, input: AddSecretInput) => {
|
||||
await db.insert(integrationSecrets).values({
|
||||
kind: input.kind,
|
||||
value: encryptSecret(input.value),
|
||||
|
||||
@@ -78,8 +78,8 @@ describe("byId should return an app by id", () => {
|
||||
session: null,
|
||||
});
|
||||
|
||||
const act = async () => await caller.byId({ id: "2" });
|
||||
await expect(act()).rejects.toThrow("App not found");
|
||||
const actAsync = async () => await caller.byId({ id: "2" });
|
||||
await expect(actAsync()).rejects.toThrow("App not found");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -174,7 +174,7 @@ describe("update should update an app", () => {
|
||||
session: null,
|
||||
});
|
||||
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.update({
|
||||
id: createId(),
|
||||
name: "Mantine",
|
||||
@@ -182,7 +182,7 @@ describe("update should update an app", () => {
|
||||
description: null,
|
||||
href: null,
|
||||
});
|
||||
await expect(act()).rejects.toThrow("App not found");
|
||||
await expect(actAsync()).rejects.toThrow("App not found");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ const defaultSession = {
|
||||
// Mock the auth module to return an empty session
|
||||
vi.mock("@homarr/auth", () => ({ auth: () => ({}) as Session }));
|
||||
|
||||
const createRandomUser = async (db: Database) => {
|
||||
const createRandomUserAsync = async (db: Database) => {
|
||||
const userId = createId();
|
||||
await db.insert(users).values({
|
||||
id: userId,
|
||||
@@ -51,8 +51,8 @@ describe("getAllBoards should return all boards accessable to the current user",
|
||||
const db = createDb();
|
||||
const caller = boardRouter.createCaller({ db, session: null });
|
||||
|
||||
const user1 = await createRandomUser(db);
|
||||
const user2 = await createRandomUser(db);
|
||||
const user1 = await createRandomUserAsync(db);
|
||||
const user2 = await createRandomUserAsync(db);
|
||||
|
||||
await db.insert(boards).values([
|
||||
{
|
||||
@@ -91,8 +91,8 @@ describe("getAllBoards should return all boards accessable to the current user",
|
||||
},
|
||||
});
|
||||
|
||||
const user1 = await createRandomUser(db);
|
||||
const user2 = await createRandomUser(db);
|
||||
const user1 = await createRandomUserAsync(db);
|
||||
const user2 = await createRandomUserAsync(db);
|
||||
|
||||
await db.insert(boards).values([
|
||||
{
|
||||
@@ -122,8 +122,8 @@ describe("getAllBoards should return all boards accessable to the current user",
|
||||
const db = createDb();
|
||||
const caller = boardRouter.createCaller({ db, session: defaultSession });
|
||||
|
||||
const user1 = await createRandomUser(db);
|
||||
const user2 = await createRandomUser(db);
|
||||
const user1 = await createRandomUserAsync(db);
|
||||
const user2 = await createRandomUserAsync(db);
|
||||
await db.insert(users).values({
|
||||
id: defaultCreatorId,
|
||||
});
|
||||
@@ -170,8 +170,8 @@ describe("getAllBoards should return all boards accessable to the current user",
|
||||
session: defaultSession,
|
||||
});
|
||||
|
||||
const user1 = await createRandomUser(db);
|
||||
const user2 = await createRandomUser(db);
|
||||
const user1 = await createRandomUserAsync(db);
|
||||
const user2 = await createRandomUserAsync(db);
|
||||
await db.insert(users).values({
|
||||
id: defaultCreatorId,
|
||||
});
|
||||
@@ -237,8 +237,8 @@ describe("getAllBoards should return all boards accessable to the current user",
|
||||
session: defaultSession,
|
||||
});
|
||||
|
||||
const user1 = await createRandomUser(db);
|
||||
const user2 = await createRandomUser(db);
|
||||
const user1 = await createRandomUserAsync(db);
|
||||
const user2 = await createRandomUserAsync(db);
|
||||
await db.insert(users).values({
|
||||
id: defaultCreatorId,
|
||||
});
|
||||
@@ -322,10 +322,10 @@ describe("createBoard should create a new board", () => {
|
||||
const caller = boardRouter.createCaller({ db, session: defaultSession });
|
||||
|
||||
// Act
|
||||
const act = async () => await caller.createBoard({ name: "newBoard" });
|
||||
const actAsync = async () => await caller.createBoard({ name: "newBoard" });
|
||||
|
||||
// Assert
|
||||
await expect(act()).rejects.toThrowError("Permission denied");
|
||||
await expect(actAsync()).rejects.toThrowError("Permission denied");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -383,11 +383,11 @@ describe("rename board should rename board", () => {
|
||||
});
|
||||
|
||||
// Act
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.renameBoard({ id: boardId, name: "Newname" });
|
||||
|
||||
// Assert
|
||||
await expect(act()).rejects.toThrowError(
|
||||
await expect(actAsync()).rejects.toThrowError(
|
||||
"Board with similar name already exists",
|
||||
);
|
||||
});
|
||||
@@ -398,11 +398,11 @@ describe("rename board should rename board", () => {
|
||||
const caller = boardRouter.createCaller({ db, session: defaultSession });
|
||||
|
||||
// Act
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.renameBoard({ id: "nonExistentBoardId", name: "newName" });
|
||||
|
||||
// Assert
|
||||
await expect(act()).rejects.toThrowError("Board not found");
|
||||
await expect(actAsync()).rejects.toThrowError("Board not found");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -485,11 +485,11 @@ describe("deleteBoard should delete board", () => {
|
||||
const caller = boardRouter.createCaller({ db, session: defaultSession });
|
||||
|
||||
// Act
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.deleteBoard({ id: "nonExistentBoardId" });
|
||||
|
||||
// Assert
|
||||
await expect(act()).rejects.toThrowError("Board not found");
|
||||
await expect(actAsync()).rejects.toThrowError("Board not found");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -552,11 +552,11 @@ describe("getBoardByName should return board by name", () => {
|
||||
await createFullBoardAsync(db, "default");
|
||||
|
||||
// Act
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.getBoardByName({ name: "nonExistentBoard" });
|
||||
|
||||
// Assert
|
||||
await expect(act()).rejects.toThrowError("Board not found");
|
||||
await expect(actAsync()).rejects.toThrowError("Board not found");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -633,7 +633,7 @@ describe("savePartialBoardSettings should save general settings", () => {
|
||||
const db = createDb();
|
||||
const caller = boardRouter.createCaller({ db, session: defaultSession });
|
||||
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.savePartialBoardSettings({
|
||||
pageTitle: "newPageTitle",
|
||||
metaTitle: "newMetaTitle",
|
||||
@@ -642,7 +642,7 @@ describe("savePartialBoardSettings should save general settings", () => {
|
||||
id: "nonExistentBoardId",
|
||||
});
|
||||
|
||||
await expect(act()).rejects.toThrowError("Board not found");
|
||||
await expect(actAsync()).rejects.toThrowError("Board not found");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1151,13 +1151,13 @@ describe("saveBoard should save full board", () => {
|
||||
const db = createDb();
|
||||
const caller = boardRouter.createCaller({ db, session: defaultSession });
|
||||
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.saveBoard({
|
||||
id: "nonExistentBoardId",
|
||||
sections: [],
|
||||
});
|
||||
|
||||
await expect(act()).rejects.toThrowError("Board not found");
|
||||
await expect(actAsync()).rejects.toThrowError("Board not found");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1168,8 +1168,8 @@ describe("getBoardPermissions should return board permissions", () => {
|
||||
const caller = boardRouter.createCaller({ db, session: defaultSession });
|
||||
const spy = vi.spyOn(boardAccess, "throwIfActionForbiddenAsync");
|
||||
|
||||
const user1 = await createRandomUser(db);
|
||||
const user2 = await createRandomUser(db);
|
||||
const user1 = await createRandomUserAsync(db);
|
||||
const user2 = await createRandomUserAsync(db);
|
||||
await db.insert(users).values({
|
||||
id: defaultCreatorId,
|
||||
});
|
||||
@@ -1250,7 +1250,7 @@ describe("saveUserBoardPermissions should save user board permissions", () => {
|
||||
const caller = boardRouter.createCaller({ db, session: defaultSession });
|
||||
const spy = vi.spyOn(boardAccess, "throwIfActionForbiddenAsync");
|
||||
|
||||
const user1 = await createRandomUser(db);
|
||||
const user1 = await createRandomUserAsync(db);
|
||||
await db.insert(users).values({
|
||||
id: defaultCreatorId,
|
||||
});
|
||||
|
||||
@@ -9,7 +9,10 @@ import { throwIfActionForbiddenAsync } from "../../board/board-access";
|
||||
|
||||
const defaultCreatorId = createId();
|
||||
|
||||
const expectActToBe = async (act: () => Promise<void>, success: boolean) => {
|
||||
const expectActToBeAsync = async (
|
||||
act: () => Promise<void>,
|
||||
success: boolean,
|
||||
) => {
|
||||
if (!success) {
|
||||
await expect(act()).rejects.toThrow("Board not found");
|
||||
return;
|
||||
@@ -55,7 +58,7 @@ describe("throwIfActionForbiddenAsync should check access to board and return bo
|
||||
);
|
||||
|
||||
// Assert
|
||||
await expectActToBe(act, expectedResult);
|
||||
await expectActToBeAsync(act, expectedResult);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -92,7 +95,7 @@ describe("throwIfActionForbiddenAsync should check access to board and return bo
|
||||
);
|
||||
|
||||
// Assert
|
||||
await expectActToBe(act, expectedResult);
|
||||
await expectActToBeAsync(act, expectedResult);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -129,7 +132,7 @@ describe("throwIfActionForbiddenAsync should check access to board and return bo
|
||||
);
|
||||
|
||||
// Assert
|
||||
await expectActToBe(act, expectedResult);
|
||||
await expectActToBeAsync(act, expectedResult);
|
||||
},
|
||||
);
|
||||
|
||||
@@ -166,7 +169,7 @@ describe("throwIfActionForbiddenAsync should check access to board and return bo
|
||||
);
|
||||
|
||||
// Assert
|
||||
await expectActToBe(act, expectedResult);
|
||||
await expectActToBeAsync(act, expectedResult);
|
||||
},
|
||||
);
|
||||
|
||||
|
||||
@@ -196,10 +196,10 @@ describe("byId should return group by id including members and permissions", ()
|
||||
});
|
||||
|
||||
// Act
|
||||
const act = async () => await caller.getById({ id: "1" });
|
||||
const actAsync = async () => await caller.getById({ id: "1" });
|
||||
|
||||
// Assert
|
||||
await expect(act()).rejects.toThrow("Group not found");
|
||||
await expect(actAsync()).rejects.toThrow("Group not found");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -235,13 +235,13 @@ describe("create should create group in database", () => {
|
||||
const longName = "a".repeat(65);
|
||||
|
||||
// Act
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.createGroup({
|
||||
name: longName,
|
||||
});
|
||||
|
||||
// Assert
|
||||
await expect(act()).rejects.toThrow("too_big");
|
||||
await expect(actAsync()).rejects.toThrow("too_big");
|
||||
});
|
||||
|
||||
test.each([
|
||||
@@ -262,10 +262,11 @@ describe("create should create group in database", () => {
|
||||
});
|
||||
|
||||
// Act
|
||||
const act = async () => await caller.createGroup({ name: nameToCreate });
|
||||
const actAsync = async () =>
|
||||
await caller.createGroup({ name: nameToCreate });
|
||||
|
||||
// Assert
|
||||
await expect(act()).rejects.toThrow("similar name");
|
||||
await expect(actAsync()).rejects.toThrow("similar name");
|
||||
},
|
||||
);
|
||||
});
|
||||
@@ -330,14 +331,14 @@ describe("update should update name with value that is no duplicate", () => {
|
||||
]);
|
||||
|
||||
// Act
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.updateGroup({
|
||||
id: groupId,
|
||||
name: updateValue,
|
||||
});
|
||||
|
||||
// Assert
|
||||
await expect(act()).rejects.toThrow("similar name");
|
||||
await expect(actAsync()).rejects.toThrow("similar name");
|
||||
},
|
||||
);
|
||||
|
||||
@@ -408,14 +409,14 @@ describe("savePermissions should save permissions for group", () => {
|
||||
});
|
||||
|
||||
// Act
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.savePermissions({
|
||||
groupId: createId(),
|
||||
permissions: ["integration-create", "board-full-access"],
|
||||
});
|
||||
|
||||
// Assert
|
||||
await expect(act()).rejects.toThrow("Group not found");
|
||||
await expect(actAsync()).rejects.toThrow("Group not found");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -468,14 +469,14 @@ describe("transferOwnership should transfer ownership of group", () => {
|
||||
});
|
||||
|
||||
// Act
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.transferOwnership({
|
||||
groupId: createId(),
|
||||
userId: createId(),
|
||||
});
|
||||
|
||||
// Assert
|
||||
await expect(act()).rejects.toThrow("Group not found");
|
||||
await expect(actAsync()).rejects.toThrow("Group not found");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -520,13 +521,13 @@ describe("deleteGroup should delete group", () => {
|
||||
});
|
||||
|
||||
// Act
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.deleteGroup({
|
||||
id: createId(),
|
||||
});
|
||||
|
||||
// Assert
|
||||
await expect(act()).rejects.toThrow("Group not found");
|
||||
await expect(actAsync()).rejects.toThrow("Group not found");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -580,14 +581,14 @@ describe("addMember should add member to group", () => {
|
||||
});
|
||||
|
||||
// Act
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.addMember({
|
||||
groupId: createId(),
|
||||
userId: createId(),
|
||||
});
|
||||
|
||||
// Assert
|
||||
await expect(act()).rejects.toThrow("Group not found");
|
||||
await expect(actAsync()).rejects.toThrow("Group not found");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -644,14 +645,14 @@ describe("removeMember should remove member from group", () => {
|
||||
});
|
||||
|
||||
// Act
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.removeMember({
|
||||
groupId: createId(),
|
||||
userId: createId(),
|
||||
});
|
||||
|
||||
// Assert
|
||||
await expect(act()).rejects.toThrow("Group not found");
|
||||
await expect(actAsync()).rejects.toThrow("Group not found");
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -76,8 +76,8 @@ describe("byId should return an integration by id", () => {
|
||||
session: null,
|
||||
});
|
||||
|
||||
const act = async () => await caller.byId({ id: "2" });
|
||||
await expect(act()).rejects.toThrow("Integration not found");
|
||||
const actAsync = async () => await caller.byId({ id: "2" });
|
||||
await expect(actAsync()).rejects.toThrow("Integration not found");
|
||||
});
|
||||
|
||||
it("should only return the public secret values", async () => {
|
||||
@@ -258,14 +258,14 @@ describe("update should update an integration", () => {
|
||||
session: null,
|
||||
});
|
||||
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.update({
|
||||
id: createId(),
|
||||
name: "Pi Hole",
|
||||
url: "http://hole.local",
|
||||
secrets: [],
|
||||
});
|
||||
await expect(act()).rejects.toThrow("Integration not found");
|
||||
await expect(actAsync()).rejects.toThrow("Integration not found");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -343,8 +343,8 @@ describe("testConnection should test the connection to an integration", () => {
|
||||
secrets,
|
||||
};
|
||||
|
||||
const act = async () => await caller.testConnection(input);
|
||||
await expect(act()).rejects.toThrow("SECRETS_NOT_DEFINED");
|
||||
const actAsync = async () => await caller.testConnection(input);
|
||||
await expect(actAsync()).rejects.toThrow("SECRETS_NOT_DEFINED");
|
||||
},
|
||||
);
|
||||
|
||||
@@ -373,8 +373,8 @@ describe("testConnection should test the connection to an integration", () => {
|
||||
secrets,
|
||||
};
|
||||
|
||||
const act = async () => await caller.testConnection(input);
|
||||
await expect(act()).resolves.toBeUndefined();
|
||||
const actAsync = async () => await caller.testConnection(input);
|
||||
await expect(actAsync()).resolves.toBeUndefined();
|
||||
},
|
||||
);
|
||||
|
||||
@@ -395,8 +395,8 @@ describe("testConnection should test the connection to an integration", () => {
|
||||
],
|
||||
};
|
||||
|
||||
const act = async () => await caller.testConnection(input);
|
||||
await expect(act()).resolves.toBeUndefined();
|
||||
const actAsync = async () => await caller.testConnection(input);
|
||||
await expect(actAsync()).resolves.toBeUndefined();
|
||||
});
|
||||
|
||||
it("should be successful when overriding one of the secrets for an existing nzbGet integration", async () => {
|
||||
@@ -439,8 +439,8 @@ describe("testConnection should test the connection to an integration", () => {
|
||||
],
|
||||
};
|
||||
|
||||
const act = async () => await caller.testConnection(input);
|
||||
await expect(act()).resolves.toBeUndefined();
|
||||
const actAsync = async () => await caller.testConnection(input);
|
||||
await expect(actAsync()).resolves.toBeUndefined();
|
||||
});
|
||||
|
||||
it("should fail when a required secret is missing for an existing nzbGet integration", async () => {
|
||||
@@ -477,8 +477,8 @@ describe("testConnection should test the connection to an integration", () => {
|
||||
],
|
||||
};
|
||||
|
||||
const act = async () => await caller.testConnection(input);
|
||||
await expect(act()).rejects.toThrow("SECRETS_NOT_DEFINED");
|
||||
const actAsync = async () => await caller.testConnection(input);
|
||||
await expect(actAsync()).rejects.toThrow("SECRETS_NOT_DEFINED");
|
||||
});
|
||||
|
||||
it("should fail when the updating integration does not exist", async () => {
|
||||
@@ -488,7 +488,7 @@ describe("testConnection should test the connection to an integration", () => {
|
||||
session: null,
|
||||
});
|
||||
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.testConnection({
|
||||
id: createId(),
|
||||
kind: "nzbGet",
|
||||
@@ -498,6 +498,6 @@ describe("testConnection should test the connection to an integration", () => {
|
||||
{ kind: "password", value: "Password123!" },
|
||||
],
|
||||
});
|
||||
await expect(act()).rejects.toThrow("SECRETS_NOT_DEFINED");
|
||||
await expect(actAsync()).rejects.toThrow("SECRETS_NOT_DEFINED");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -183,9 +183,9 @@ describe("delete should remove invite by id", () => {
|
||||
});
|
||||
|
||||
// Act
|
||||
const act = async () => await caller.deleteInvite({ id: createId() });
|
||||
const actAsync = async () => await caller.deleteInvite({ id: createId() });
|
||||
|
||||
// Assert
|
||||
await expect(act()).rejects.toThrow("not found");
|
||||
await expect(actAsync()).rejects.toThrow("not found");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -27,14 +27,14 @@ describe("initUser should initialize the first user", () => {
|
||||
password: "test",
|
||||
});
|
||||
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.initUser({
|
||||
username: "test",
|
||||
password: "12345678",
|
||||
confirmPassword: "12345678",
|
||||
});
|
||||
|
||||
await expect(act()).rejects.toThrow("User already exists");
|
||||
await expect(actAsync()).rejects.toThrow("User already exists");
|
||||
});
|
||||
|
||||
it("should create a user if none exists", async () => {
|
||||
@@ -66,14 +66,14 @@ describe("initUser should initialize the first user", () => {
|
||||
session: null,
|
||||
});
|
||||
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.initUser({
|
||||
username: "test",
|
||||
password: "12345678",
|
||||
confirmPassword: "12345679",
|
||||
});
|
||||
|
||||
await expect(act()).rejects.toThrow("Passwords do not match");
|
||||
await expect(actAsync()).rejects.toThrow("Passwords do not match");
|
||||
});
|
||||
|
||||
it("should not create a user if the password is too short", async () => {
|
||||
@@ -83,14 +83,14 @@ describe("initUser should initialize the first user", () => {
|
||||
session: null,
|
||||
});
|
||||
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.initUser({
|
||||
username: "test",
|
||||
password: "1234567",
|
||||
confirmPassword: "1234567",
|
||||
});
|
||||
|
||||
await expect(act()).rejects.toThrow("too_small");
|
||||
await expect(actAsync()).rejects.toThrow("too_small");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -175,7 +175,7 @@ describe("register should create a user with valid invitation", () => {
|
||||
});
|
||||
|
||||
// Act
|
||||
const act = async () =>
|
||||
const actAsync = async () =>
|
||||
await caller.register({
|
||||
inviteId,
|
||||
token: inviteToken,
|
||||
@@ -186,7 +186,7 @@ describe("register should create a user with valid invitation", () => {
|
||||
});
|
||||
|
||||
// Assert
|
||||
await expect(act()).rejects.toThrow("Invalid invite");
|
||||
await expect(actAsync()).rejects.toThrow("Invalid invite");
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { TRPCError } from "@trpc/server";
|
||||
import { observable } from "@trpc/server/observable";
|
||||
|
||||
import { createSalt, hashPassword } from "@homarr/auth";
|
||||
import { createSaltAsync, hashPasswordAsync } from "@homarr/auth";
|
||||
import type { Database } from "@homarr/db";
|
||||
import { and, createId, eq, schema } from "@homarr/db";
|
||||
import { invites, users } from "@homarr/db/schema/sqlite";
|
||||
@@ -27,7 +27,7 @@ export const userRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
|
||||
await createUser(ctx.db, input);
|
||||
await createUserAsync(ctx.db, input);
|
||||
}),
|
||||
register: publicProcedure
|
||||
.input(validation.user.registrationApi)
|
||||
@@ -51,14 +51,14 @@ export const userRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
|
||||
await createUser(ctx.db, input);
|
||||
await createUserAsync(ctx.db, input);
|
||||
// Delete invite as it's used
|
||||
await ctx.db.delete(invites).where(inviteWhere);
|
||||
}),
|
||||
create: publicProcedure
|
||||
.input(validation.user.create)
|
||||
.mutation(async ({ ctx, input }) => {
|
||||
await createUser(ctx.db, input);
|
||||
await createUserAsync(ctx.db, input);
|
||||
}),
|
||||
setProfileImage: protectedProcedure
|
||||
.input(
|
||||
@@ -209,7 +209,7 @@ export const userRouter = createTRPCRouter({
|
||||
});
|
||||
}
|
||||
|
||||
const previousPasswordHash = await hashPassword(
|
||||
const previousPasswordHash = await hashPasswordAsync(
|
||||
input.previousPassword,
|
||||
dbUser.salt ?? "",
|
||||
);
|
||||
@@ -223,8 +223,8 @@ export const userRouter = createTRPCRouter({
|
||||
}
|
||||
}
|
||||
|
||||
const salt = await createSalt();
|
||||
const hashedPassword = await hashPassword(input.password, salt);
|
||||
const salt = await createSaltAsync();
|
||||
const hashedPassword = await hashPasswordAsync(input.password, salt);
|
||||
await ctx.db
|
||||
.update(users)
|
||||
.set({
|
||||
@@ -233,7 +233,7 @@ export const userRouter = createTRPCRouter({
|
||||
.where(eq(users.id, input.userId));
|
||||
}),
|
||||
setMessage: publicProcedure.input(z.string()).mutation(async ({ input }) => {
|
||||
await exampleChannel.publish({ message: input });
|
||||
await exampleChannel.publishAsync({ message: input });
|
||||
}),
|
||||
test: publicProcedure.subscription(() => {
|
||||
return observable<{ message: string }>((emit) => {
|
||||
@@ -244,12 +244,12 @@ export const userRouter = createTRPCRouter({
|
||||
}),
|
||||
});
|
||||
|
||||
const createUser = async (
|
||||
const createUserAsync = async (
|
||||
db: Database,
|
||||
input: z.infer<typeof validation.user.create>,
|
||||
) => {
|
||||
const salt = await createSalt();
|
||||
const hashedPassword = await hashPassword(input.password, salt);
|
||||
const salt = await createSaltAsync();
|
||||
const hashedPassword = await hashPasswordAsync(input.password, salt);
|
||||
|
||||
const userId = createId();
|
||||
await db.insert(schema.users).values({
|
||||
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
sessionTokenCookieName,
|
||||
} from "./session";
|
||||
|
||||
export const getCurrentUserPermissions = async (
|
||||
export const getCurrentUserPermissionsAsync = async (
|
||||
db: Database,
|
||||
userId: string,
|
||||
) => {
|
||||
@@ -47,7 +47,7 @@ export const createSessionCallback = (
|
||||
...session.user,
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
permissions: await getCurrentUserPermissions(db, user.id),
|
||||
permissions: await getCurrentUserPermissionsAsync(db, user.id),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -20,4 +20,7 @@ export * from "./security";
|
||||
export const createHandlers = (isCredentialsRequest: boolean) =>
|
||||
createConfiguration(isCredentialsRequest);
|
||||
|
||||
export { getSessionFromToken, sessionTokenCookieName } from "./session";
|
||||
export {
|
||||
getSessionFromTokenAsync as getSessionFromToken,
|
||||
sessionTokenCookieName,
|
||||
} from "./session";
|
||||
|
||||
@@ -22,6 +22,7 @@ export const createCredentialsConfiguration = (db: Database) =>
|
||||
type: "password",
|
||||
},
|
||||
},
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
async authorize(credentials) {
|
||||
const data = await validation.user.signIn.parseAsync(credentials);
|
||||
|
||||
|
||||
@@ -4,18 +4,18 @@ import { createId } from "@homarr/db";
|
||||
import { users } from "@homarr/db/schema/sqlite";
|
||||
import { createDb } from "@homarr/db/test";
|
||||
|
||||
import { createSalt, hashPassword } from "../../security";
|
||||
import { createSaltAsync, hashPasswordAsync } from "../../security";
|
||||
import { createCredentialsConfiguration } from "../credentials";
|
||||
|
||||
describe("Credentials authorization", () => {
|
||||
it("should authorize user with correct credentials", async () => {
|
||||
const db = createDb();
|
||||
const userId = createId();
|
||||
const salt = await createSalt();
|
||||
const salt = await createSaltAsync();
|
||||
await db.insert(users).values({
|
||||
id: userId,
|
||||
name: "test",
|
||||
password: await hashPassword("test", salt),
|
||||
password: await hashPasswordAsync("test", salt),
|
||||
salt,
|
||||
});
|
||||
const result = await createCredentialsConfiguration(db).authorize({
|
||||
@@ -38,11 +38,11 @@ describe("Credentials authorization", () => {
|
||||
it(`should not authorize user with incorrect credentials (${password})`, async () => {
|
||||
const db = createDb();
|
||||
const userId = createId();
|
||||
const salt = await createSalt();
|
||||
const salt = await createSaltAsync();
|
||||
await db.insert(users).values({
|
||||
id: userId,
|
||||
name: "test",
|
||||
password: await hashPassword("test", salt),
|
||||
password: await hashPasswordAsync("test", salt),
|
||||
salt,
|
||||
});
|
||||
const result = await createCredentialsConfiguration(db).authorize({
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import bcrypt from "bcrypt";
|
||||
|
||||
export const createSalt = async () => {
|
||||
export const createSaltAsync = async () => {
|
||||
return bcrypt.genSalt(10);
|
||||
};
|
||||
|
||||
export const hashPassword = async (password: string, salt: string) => {
|
||||
export const hashPasswordAsync = async (password: string, salt: string) => {
|
||||
return bcrypt.hash(password, salt);
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { Session } from "@auth/core/types";
|
||||
|
||||
import type { Database } from "@homarr/db";
|
||||
|
||||
import { getCurrentUserPermissions } from "./callbacks";
|
||||
import { getCurrentUserPermissionsAsync } from "./callbacks";
|
||||
|
||||
export const sessionMaxAgeInSeconds = 30 * 24 * 60 * 60; // 30 days
|
||||
export const sessionTokenCookieName = "next-auth.session-token";
|
||||
@@ -16,7 +16,7 @@ export const generateSessionToken = () => {
|
||||
return randomUUID();
|
||||
};
|
||||
|
||||
export const getSessionFromToken = async (
|
||||
export const getSessionFromTokenAsync = async (
|
||||
db: Database,
|
||||
token: string | undefined,
|
||||
): Promise<Session | null> => {
|
||||
@@ -48,7 +48,7 @@ export const getSessionFromToken = async (
|
||||
return {
|
||||
user: {
|
||||
...session.user,
|
||||
permissions: await getCurrentUserPermissions(db, session.user.id),
|
||||
permissions: await getCurrentUserPermissionsAsync(db, session.user.id),
|
||||
},
|
||||
expires: session.expires.toISOString(),
|
||||
};
|
||||
|
||||
@@ -18,7 +18,7 @@ import * as definitions from "@homarr/definitions";
|
||||
import {
|
||||
createSessionCallback,
|
||||
createSignInCallback,
|
||||
getCurrentUserPermissions,
|
||||
getCurrentUserPermissionsAsync,
|
||||
} from "../callbacks";
|
||||
|
||||
describe("getCurrentUserPermissions", () => {
|
||||
@@ -30,7 +30,7 @@ describe("getCurrentUserPermissions", () => {
|
||||
});
|
||||
|
||||
const userId = "1";
|
||||
const result = await getCurrentUserPermissions(db, userId);
|
||||
const result = await getCurrentUserPermissionsAsync(db, userId);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
test("should return permissions for user", async () => {
|
||||
@@ -56,7 +56,7 @@ describe("getCurrentUserPermissions", () => {
|
||||
permission: "admin",
|
||||
});
|
||||
|
||||
const result = await getCurrentUserPermissions(db, mockId);
|
||||
const result = await getCurrentUserPermissionsAsync(db, mockId);
|
||||
expect(result).toEqual(["board-create"]);
|
||||
expect(getPermissionsWithChildrenMock).toHaveBeenCalledWith(["admin"]);
|
||||
});
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { createSalt, hashPassword } from "../security";
|
||||
import { createSaltAsync, hashPasswordAsync } from "../security";
|
||||
|
||||
describe("createSalt should return a salt", () => {
|
||||
it("should return a salt", async () => {
|
||||
const result = await createSalt();
|
||||
const result = await createSaltAsync();
|
||||
expect(result).toBeDefined();
|
||||
expect(result.length).toBeGreaterThan(25);
|
||||
});
|
||||
it("should return a different salt each time", async () => {
|
||||
const result1 = await createSalt();
|
||||
const result2 = await createSalt();
|
||||
const result1 = await createSaltAsync();
|
||||
const result2 = await createSaltAsync();
|
||||
expect(result1).not.toEqual(result2);
|
||||
});
|
||||
});
|
||||
@@ -18,8 +18,8 @@ describe("createSalt should return a salt", () => {
|
||||
describe("hashPassword should return a hash", () => {
|
||||
it("should return a hash", async () => {
|
||||
const password = "password";
|
||||
const salt = await createSalt();
|
||||
const result = await hashPassword(password, salt);
|
||||
const salt = await createSaltAsync();
|
||||
const result = await hashPasswordAsync(password, salt);
|
||||
expect(result).toBeDefined();
|
||||
expect(result.length).toBeGreaterThan(55);
|
||||
expect(result).not.toEqual(password);
|
||||
@@ -27,20 +27,20 @@ describe("hashPassword should return a hash", () => {
|
||||
it("should return a different hash each time", async () => {
|
||||
const password = "password";
|
||||
const password2 = "another password";
|
||||
const salt = await createSalt();
|
||||
const salt = await createSaltAsync();
|
||||
|
||||
const result1 = await hashPassword(password, salt);
|
||||
const result2 = await hashPassword(password2, salt);
|
||||
const result1 = await hashPasswordAsync(password, salt);
|
||||
const result2 = await hashPasswordAsync(password2, salt);
|
||||
|
||||
expect(result1).not.toEqual(result2);
|
||||
});
|
||||
it("should return a different hash for the same password with different salts", async () => {
|
||||
const password = "password";
|
||||
const salt1 = await createSalt();
|
||||
const salt2 = await createSalt();
|
||||
const salt1 = await createSaltAsync();
|
||||
const salt2 = await createSaltAsync();
|
||||
|
||||
const result1 = await hashPassword(password, salt1);
|
||||
const result2 = await hashPassword(password, salt2);
|
||||
const result1 = await hashPasswordAsync(password, salt1);
|
||||
const result2 = await hashPasswordAsync(password, salt2);
|
||||
|
||||
expect(result1).not.toEqual(result2);
|
||||
});
|
||||
|
||||
@@ -46,7 +46,7 @@ export const createSubPubChannel = <TData>(name: string) => {
|
||||
* Publish data to the channel with last data saved.
|
||||
* @param data data to be published
|
||||
*/
|
||||
publish: async (data: TData) => {
|
||||
publishAsync: async (data: TData) => {
|
||||
await lastDataClient.set(lastChannelName, superjson.stringify(data));
|
||||
await publisher.publish(channelName, superjson.stringify(data));
|
||||
},
|
||||
@@ -64,11 +64,11 @@ type WithId<TItem> = TItem & { _id: string };
|
||||
*/
|
||||
export const createQueueChannel = <TItem>(name: string) => {
|
||||
const queueChannelName = `queue:${name}`;
|
||||
const getData = async () => {
|
||||
const getDataAsync = async () => {
|
||||
const data = await queueClient.get(queueChannelName);
|
||||
return data ? superjson.parse<WithId<TItem>[]>(data) : [];
|
||||
};
|
||||
const setData = async (data: WithId<TItem>[]) => {
|
||||
const setDataAsync = async (data: WithId<TItem>[]) => {
|
||||
await queueClient.set(queueChannelName, superjson.stringify(data));
|
||||
};
|
||||
|
||||
@@ -77,22 +77,22 @@ export const createQueueChannel = <TItem>(name: string) => {
|
||||
* Add a new queue execution.
|
||||
* @param data data to be stored in the queue execution to run it later
|
||||
*/
|
||||
add: async (data: TItem) => {
|
||||
const items = await getData();
|
||||
addAsync: async (data: TItem) => {
|
||||
const items = await getDataAsync();
|
||||
items.push({ _id: createId(), ...data });
|
||||
await setData(items);
|
||||
await setDataAsync(items);
|
||||
},
|
||||
/**
|
||||
* Get all queue executions.
|
||||
*/
|
||||
all: getData,
|
||||
all: getDataAsync,
|
||||
/**
|
||||
* Get a queue execution by its id.
|
||||
* @param id id of the queue execution (stored under _id key)
|
||||
* @returns queue execution or undefined if not found
|
||||
*/
|
||||
byId: async (id: string) => {
|
||||
const items = await getData();
|
||||
byIdAsync: async (id: string) => {
|
||||
const items = await getDataAsync();
|
||||
return items.find((item) => item._id === id);
|
||||
},
|
||||
/**
|
||||
@@ -100,17 +100,17 @@ export const createQueueChannel = <TItem>(name: string) => {
|
||||
* @param filter callback function that returns true if the item should be included in the result
|
||||
* @returns filtered queue executions
|
||||
*/
|
||||
filter: async (filter: (item: WithId<TItem>) => boolean) => {
|
||||
const items = await getData();
|
||||
filterAsync: async (filter: (item: WithId<TItem>) => boolean) => {
|
||||
const items = await getDataAsync();
|
||||
return items.filter(filter);
|
||||
},
|
||||
/**
|
||||
* Marks an queue execution as done, by deleting it.
|
||||
* @param id id of the queue execution (stored under _id key)
|
||||
*/
|
||||
markAsDone: async (id: string) => {
|
||||
const items = await getData();
|
||||
await setData(items.filter((item) => item._id !== id));
|
||||
markAsDoneAsync: async (id: string) => {
|
||||
const items = await getDataAsync();
|
||||
await setDataAsync(items.filter((item) => item._id !== id));
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@@ -4,7 +4,9 @@ import { api } from "@homarr/api/server";
|
||||
|
||||
import type { WidgetProps } from "../definition";
|
||||
|
||||
export default async function getServerData({ options }: WidgetProps<"app">) {
|
||||
export default async function getServerDataAsync({
|
||||
options,
|
||||
}: WidgetProps<"app">) {
|
||||
try {
|
||||
const app = await api.app.byId({ id: options.appId });
|
||||
return { app };
|
||||
|
||||
Reference in New Issue
Block a user