a lot of things
This commit is contained in:
@@ -5,6 +5,7 @@ import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||
import { authMiddleware } from "../middleware/authorization";
|
||||
import { z } from "zod";
|
||||
import { ValueType } from "../../modules/credentials/credentialTypeDefs";
|
||||
|
||||
/* /v1/credential-type */
|
||||
export default createRoute(
|
||||
@@ -24,13 +25,15 @@ export default createRoute(
|
||||
name: z.string(),
|
||||
required: z.boolean(),
|
||||
secure: z.boolean(),
|
||||
valueType: z.enum(["plain_text", "password"]),
|
||||
valueType: z.enum(Object.values(ValueType)),
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
const data = schema.parse(body);
|
||||
|
||||
console.log("Creating Credential Type with data:", data);
|
||||
|
||||
const credentialType = await credentialTypes.create(data as any);
|
||||
|
||||
const response = apiResponse.created(
|
||||
|
||||
@@ -5,6 +5,7 @@ import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||
import { authMiddleware } from "../middleware/authorization";
|
||||
import { z } from "zod";
|
||||
import { ValueType } from "../../modules/credentials/credentialTypeDefs";
|
||||
|
||||
/* /v1/credential-type/:id */
|
||||
export default createRoute(
|
||||
@@ -26,7 +27,7 @@ export default createRoute(
|
||||
name: z.string(),
|
||||
required: z.boolean(),
|
||||
secure: z.boolean(),
|
||||
valueType: z.enum(["plain_text", "password"]),
|
||||
valueType: z.enum(Object.values(ValueType)),
|
||||
}),
|
||||
)
|
||||
.optional(),
|
||||
|
||||
@@ -16,6 +16,7 @@ export default createRoute(
|
||||
|
||||
const schema = z.object({
|
||||
name: z.string().min(1, "Name is required"),
|
||||
notes: z.string().optional(),
|
||||
typeId: z.string().min(1, "Type ID is required"),
|
||||
companyId: z.string().min(1, "Company ID is required"),
|
||||
fields: z.array(
|
||||
|
||||
@@ -5,9 +5,12 @@ import { default as update } from "./update";
|
||||
import { default as updateFields } from "./updateFields";
|
||||
import { default as fetchFields } from "./fetchFields";
|
||||
import { default as readSecureValues } from "./readSecureValues";
|
||||
import { default as readSecureValue } from "./readSecureValue";
|
||||
import { default as deleteCredential } from "./delete";
|
||||
import { default as valueTypes } from "./valueTypes";
|
||||
|
||||
export {
|
||||
valueTypes,
|
||||
fetch,
|
||||
fetchByCompany,
|
||||
create,
|
||||
@@ -15,5 +18,6 @@ export {
|
||||
updateFields,
|
||||
fetchFields,
|
||||
readSecureValues,
|
||||
readSecureValue,
|
||||
deleteCredential as delete,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
import { Hono } from "hono/tiny";
|
||||
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||
import { credentials } from "../../managers/credentials";
|
||||
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||
import { authMiddleware } from "../middleware/authorization";
|
||||
|
||||
/* GET /v1/credential/credentials/:id/secure-values/:fieldId */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/credentials/:id/secure-values/:fieldId"],
|
||||
|
||||
async (c) => {
|
||||
const credential = await credentials.fetch(c.req.param("id"));
|
||||
const fieldId = c.req.param("fieldId");
|
||||
const value = await credential.readSecureFieldValue(fieldId);
|
||||
|
||||
const response = apiResponse.successful(
|
||||
"Secure Value Fetched Successfully!",
|
||||
{ fieldId, value },
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({
|
||||
permissions: ["credential.fetch", "credential.secure_values.read"],
|
||||
}),
|
||||
);
|
||||
@@ -17,11 +17,29 @@ export default createRoute(
|
||||
|
||||
const schema = z.object({
|
||||
name: z.string().optional(),
|
||||
notes: z.string().nullable().optional(),
|
||||
fields: z
|
||||
.array(
|
||||
z.object({
|
||||
fieldId: z.string(),
|
||||
value: z.string(),
|
||||
}),
|
||||
)
|
||||
.optional(),
|
||||
});
|
||||
|
||||
const data = schema.parse(body);
|
||||
|
||||
await credential.update(data);
|
||||
if (data.fields) {
|
||||
await credential.validateAndUpdateFields(data.fields);
|
||||
}
|
||||
|
||||
if (data.name !== undefined || data.notes !== undefined) {
|
||||
await credential.update({
|
||||
...(data.name !== undefined && { name: data.name }),
|
||||
...(data.notes !== undefined && { notes: data.notes }),
|
||||
});
|
||||
}
|
||||
|
||||
const response = apiResponse.successful(
|
||||
"Credential Updated Successfully!",
|
||||
|
||||
@@ -18,7 +18,6 @@ export default createRoute(
|
||||
const schema = z.object({
|
||||
fields: z.array(
|
||||
z.object({
|
||||
id: z.string(),
|
||||
fieldId: z.string(),
|
||||
value: z.string(),
|
||||
}),
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||
import { ValueType } from "../../modules/credentials/credentialTypeDefs";
|
||||
import { authMiddleware } from "../middleware/authorization";
|
||||
|
||||
/* GET /v1/credential/valuetypes */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/valuetypes"],
|
||||
|
||||
async (c) => {
|
||||
const valueTypes = Object.values(ValueType);
|
||||
|
||||
const response = apiResponse.successful(
|
||||
"Value Types Fetched Successfully!",
|
||||
valueTypes,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware(),
|
||||
);
|
||||
@@ -1,7 +1,9 @@
|
||||
import { Hono } from "hono";
|
||||
import * as userRoutes from "../user/@me";
|
||||
import * as meRoutes from "../user/@me";
|
||||
import * as userRoutes from "../user";
|
||||
|
||||
const authRouter = new Hono();
|
||||
Object.values(meRoutes).map((r) => authRouter.route("/", r));
|
||||
Object.values(userRoutes).map((r) => authRouter.route("/", r));
|
||||
|
||||
export default authRouter;
|
||||
|
||||
@@ -1,13 +1,22 @@
|
||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||
import { z } from "zod";
|
||||
import { apiResponse } from "../../../modules/api-utils/apiResponse";
|
||||
import { createRoute } from "../../../modules/api-utils/createRoute";
|
||||
import { authMiddleware } from "../../middleware/authorization";
|
||||
|
||||
const updateSchema = z
|
||||
.object({
|
||||
name: z.string().optional(),
|
||||
image: z.string().optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
export default createRoute(
|
||||
"patch",
|
||||
["/@me"],
|
||||
async (c) => {
|
||||
const updatedUser = await c.get("user")?.update(await c.req.json());
|
||||
const body = updateSchema.parse(await c.req.json());
|
||||
const updatedUser = await c.get("user")?.update(body);
|
||||
const response = apiResponse.successful(
|
||||
"Successfully updated user.",
|
||||
updatedUser?.toJson(),
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||
import { z } from "zod";
|
||||
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||
import { authMiddleware } from "../middleware/authorization";
|
||||
import { users } from "../../managers/users";
|
||||
import GenericError from "../../Errors/GenericError";
|
||||
|
||||
const checkPermissionSchema = z.object({
|
||||
permissions: z
|
||||
.array(z.string().min(1, "Permission node cannot be empty"))
|
||||
.min(1, "At least one permission is required"),
|
||||
});
|
||||
|
||||
/* POST /v1/user/users/:identifier/check-permission */
|
||||
export default createRoute(
|
||||
"post",
|
||||
["/users/:identifier/check-permission"],
|
||||
|
||||
async (c) => {
|
||||
const identifier = c.req.param("identifier");
|
||||
|
||||
const user = await users.fetchUser({ id: identifier });
|
||||
if (!user)
|
||||
throw new GenericError({
|
||||
name: "UserNotFound",
|
||||
message: `User with identifier '${identifier}' was not found.`,
|
||||
status: 404,
|
||||
});
|
||||
|
||||
const body = await c.req.json();
|
||||
const { permissions } = checkPermissionSchema.parse(body);
|
||||
|
||||
const results = await Promise.all(
|
||||
permissions.map(async (permission) => ({
|
||||
permission,
|
||||
hasPermission: await user.hasPermission(permission),
|
||||
})),
|
||||
);
|
||||
|
||||
const response = apiResponse.successful("Permission check completed.", {
|
||||
results,
|
||||
});
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({ permissions: ["user.read.other"] }),
|
||||
);
|
||||
@@ -0,0 +1,34 @@
|
||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||
import { authMiddleware } from "../middleware/authorization";
|
||||
import { users } from "../../managers/users";
|
||||
import GenericError from "../../Errors/GenericError";
|
||||
|
||||
/* DELETE /v1/user/users/:identifier */
|
||||
export default createRoute(
|
||||
"delete",
|
||||
["/users/:identifier"],
|
||||
|
||||
async (c) => {
|
||||
const identifier = c.req.param("identifier");
|
||||
|
||||
const user = await users.fetchUser({ id: identifier });
|
||||
if (!user)
|
||||
throw new GenericError({
|
||||
name: "UserNotFound",
|
||||
message: `User with identifier '${identifier}' was not found.`,
|
||||
status: 404,
|
||||
});
|
||||
|
||||
const userData = user.toJson();
|
||||
await users.deleteUser(user.id);
|
||||
|
||||
const response = apiResponse.successful(
|
||||
"User Deleted Successfully!",
|
||||
userData,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({ permissions: ["user.delete.other"] }),
|
||||
);
|
||||
@@ -0,0 +1,31 @@
|
||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||
import { authMiddleware } from "../middleware/authorization";
|
||||
import { users } from "../../managers/users";
|
||||
import GenericError from "../../Errors/GenericError";
|
||||
|
||||
/* GET /v1/user/users/:identifier */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/users/:identifier"],
|
||||
|
||||
async (c) => {
|
||||
const identifier = c.req.param("identifier");
|
||||
|
||||
const user = await users.fetchUser({ id: identifier });
|
||||
if (!user)
|
||||
throw new GenericError({
|
||||
name: "UserNotFound",
|
||||
message: `User with identifier '${identifier}' was not found.`,
|
||||
status: 404,
|
||||
});
|
||||
|
||||
const response = apiResponse.successful(
|
||||
"User Fetched Successfully!",
|
||||
user.toJson(),
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({ permissions: ["user.read.other"] }),
|
||||
);
|
||||
@@ -0,0 +1,23 @@
|
||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||
import { authMiddleware } from "../middleware/authorization";
|
||||
import { users } from "../../managers/users";
|
||||
|
||||
/* GET /v1/user/users */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/users"],
|
||||
|
||||
async (c) => {
|
||||
const allUsers = await users.fetchAllUsers();
|
||||
const usersArray = allUsers.map((u) => u.toJson());
|
||||
|
||||
const response = apiResponse.successful(
|
||||
"Users Fetched Successfully!",
|
||||
usersArray,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({ permissions: ["user.read.other", "user.list.other"] }),
|
||||
);
|
||||
@@ -0,0 +1,34 @@
|
||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||
import { authMiddleware } from "../middleware/authorization";
|
||||
import { users } from "../../managers/users";
|
||||
import GenericError from "../../Errors/GenericError";
|
||||
|
||||
/* GET /v1/user/users/:identifier/roles */
|
||||
export default createRoute(
|
||||
"get",
|
||||
["/users/:identifier/roles"],
|
||||
|
||||
async (c) => {
|
||||
const identifier = c.req.param("identifier");
|
||||
|
||||
const user = await users.fetchUser({ id: identifier });
|
||||
if (!user)
|
||||
throw new GenericError({
|
||||
name: "UserNotFound",
|
||||
message: `User with identifier '${identifier}' was not found.`,
|
||||
status: 404,
|
||||
});
|
||||
|
||||
const roles = await user.fetchRoles();
|
||||
const rolesArray = roles.map((r) => r.toJson({ viewPermissions: true }));
|
||||
|
||||
const response = apiResponse.successful(
|
||||
"User Roles Fetched Successfully!",
|
||||
rolesArray,
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({ permissions: ["user.read.other", "role.read"] }),
|
||||
);
|
||||
@@ -0,0 +1,6 @@
|
||||
export { default as fetch } from "./fetch";
|
||||
export { default as fetchAll } from "./fetchAll";
|
||||
export { default as update } from "./update";
|
||||
export { default as deleteUser } from "./delete";
|
||||
export { default as fetchRoles } from "./fetchRoles";
|
||||
export { default as checkPermission } from "./checkPermission";
|
||||
@@ -0,0 +1,68 @@
|
||||
import { ContentfulStatusCode } from "hono/utils/http-status";
|
||||
import { z } from "zod";
|
||||
import { apiResponse } from "../../modules/api-utils/apiResponse";
|
||||
import { createRoute } from "../../modules/api-utils/createRoute";
|
||||
import { authMiddleware } from "../middleware/authorization";
|
||||
import { users } from "../../managers/users";
|
||||
import GenericError from "../../Errors/GenericError";
|
||||
|
||||
const updateSchema = z
|
||||
.object({
|
||||
name: z.string().optional(),
|
||||
image: z.string().optional(),
|
||||
roles: z.array(z.string()).optional(),
|
||||
permissions: z.array(z.string()).optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
/* PATCH /v1/user/users/:identifier */
|
||||
export default createRoute(
|
||||
"patch",
|
||||
["/users/:identifier"],
|
||||
|
||||
async (c) => {
|
||||
const identifier = c.req.param("identifier");
|
||||
const requestingUser = c.get("user");
|
||||
|
||||
const user = await users.fetchUser({ id: identifier });
|
||||
if (!user)
|
||||
throw new GenericError({
|
||||
name: "UserNotFound",
|
||||
message: `User with identifier '${identifier}' was not found.`,
|
||||
status: 404,
|
||||
});
|
||||
|
||||
const body = updateSchema.parse(await c.req.json());
|
||||
|
||||
if (body.roles && !(await requestingUser.hasPermission("user.roles.other")))
|
||||
throw new GenericError({
|
||||
name: "InsufficientPermission",
|
||||
message: "You do not have permission to modify roles on another user.",
|
||||
status: 403,
|
||||
});
|
||||
|
||||
if (
|
||||
body.permissions &&
|
||||
!(await requestingUser.hasPermission("user.permissions.other"))
|
||||
)
|
||||
throw new GenericError({
|
||||
name: "InsufficientPermission",
|
||||
message:
|
||||
"You do not have permission to modify permissions on another user.",
|
||||
status: 403,
|
||||
});
|
||||
|
||||
const { roles: roleIds, permissions, ...profileData } = body;
|
||||
|
||||
if (Object.keys(profileData).length > 0) await user.update(profileData);
|
||||
if (roleIds) await user.setRoles(roleIds);
|
||||
if (permissions) await user.setPermissions(permissions);
|
||||
|
||||
const response = apiResponse.successful(
|
||||
"User Updated Successfully!",
|
||||
user.toJson(),
|
||||
);
|
||||
return c.json(response, response.status as ContentfulStatusCode);
|
||||
},
|
||||
authMiddleware({ permissions: ["user.write.other"] }),
|
||||
);
|
||||
Reference in New Issue
Block a user