feat: implement permissions management with new Permission interface and refactor API key handlers
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
export interface Permission {
|
||||
name: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export const IMPORT_PERMISSIONS: Permission[] = [
|
||||
{ name: "asset.read", description: "Check for existing assets" },
|
||||
{ name: "asset.upload", description: "Upload new assets" },
|
||||
{ name: "album.read", description: "Read album data" },
|
||||
{ name: "album.create", description: "Create new albums" },
|
||||
{ name: "album.update", description: "Add assets to albums" },
|
||||
{ name: "tag.create", description: "Tag imported assets" },
|
||||
{ name: "tag.asset", description: "Assign tags to assets" },
|
||||
];
|
||||
|
||||
export const WORKFLOW_PERMISSIONS: Permission[] = [
|
||||
{ name: "asset.read", description: "Query and filter assets" },
|
||||
{ name: "asset.update", description: "Favorite, archive, update metadata" },
|
||||
{ name: "album.read", description: "Read album data" },
|
||||
{ name: "album.create", description: "Create new albums" },
|
||||
{ name: "album.update", description: "Add/remove assets from albums" },
|
||||
{ name: "tag.create", description: "Create and assign tags" },
|
||||
];
|
||||
|
||||
export const getPermissionNames = (permissions: Permission[]): string[] =>
|
||||
permissions.map((p) => p.name);
|
||||
@@ -5,17 +5,10 @@ import { getCurrentUser } from "@/handlers/serverUtils/user.utils";
|
||||
import { getUserHeaders } from "@/helpers/user.helper";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
import { IMPORT_PERMISSIONS, getPermissionNames } from "@/config/permissions";
|
||||
|
||||
export const IMPORT_API_KEY_SETTING = "import_api_key";
|
||||
const IMPORT_KEY_NAME = "Power Tools Import Key";
|
||||
const IMPORT_PERMISSIONS = [
|
||||
"asset.read",
|
||||
"asset.upload",
|
||||
"album.read",
|
||||
"album.create",
|
||||
"album.update",
|
||||
"tag.create",
|
||||
];
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method !== "POST") return res.status(405).json({ message: "Method not allowed" });
|
||||
@@ -26,7 +19,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
const immichRes = await fetch(`${ENV.IMMICH_URL}/api/api-keys`, {
|
||||
method: "POST",
|
||||
headers: getUserHeaders(currentUser, { "Content-Type": "application/json" }),
|
||||
body: JSON.stringify({ name: IMPORT_KEY_NAME, permissions: IMPORT_PERMISSIONS }),
|
||||
body: JSON.stringify({ name: IMPORT_KEY_NAME, permissions: getPermissionNames(IMPORT_PERMISSIONS) }),
|
||||
});
|
||||
|
||||
if (!immichRes.ok) {
|
||||
|
||||
@@ -5,17 +5,10 @@ import { getCurrentUser } from "@/handlers/serverUtils/user.utils";
|
||||
import { getUserHeaders } from "@/helpers/user.helper";
|
||||
import { and, eq } from "drizzle-orm";
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
import { WORKFLOW_PERMISSIONS, getPermissionNames } from "@/config/permissions";
|
||||
|
||||
const WORKFLOW_API_KEY_SETTING = "workflow_api_key";
|
||||
const WORKFLOW_KEY_NAME = "Power Tools Workflow Key";
|
||||
const WORKFLOW_PERMISSIONS = [
|
||||
"asset.read",
|
||||
"asset.update",
|
||||
"album.read",
|
||||
"album.create",
|
||||
"album.update",
|
||||
"tag.create",
|
||||
];
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method !== "POST") return res.status(405).json({ message: "Method not allowed" });
|
||||
@@ -27,7 +20,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
const immichRes = await fetch(`${ENV.IMMICH_URL}/api/api-keys`, {
|
||||
method: "POST",
|
||||
headers: getUserHeaders(currentUser, { "Content-Type": "application/json" }),
|
||||
body: JSON.stringify({ name: WORKFLOW_KEY_NAME, permissions: WORKFLOW_PERMISSIONS }),
|
||||
body: JSON.stringify({ name: WORKFLOW_KEY_NAME, permissions: getPermissionNames(WORKFLOW_PERMISSIONS) }),
|
||||
});
|
||||
|
||||
if (!immichRes.ok) {
|
||||
|
||||
@@ -1,14 +1,7 @@
|
||||
import { ENV } from "@/config/environment";
|
||||
import { getCurrentUser } from "@/handlers/serverUtils/user.utils";
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
const WORKFLOW_PERMISSIONS = [
|
||||
"asset.read",
|
||||
"asset.update",
|
||||
"album.create",
|
||||
"album.update",
|
||||
"tag.create",
|
||||
];
|
||||
import { WORKFLOW_PERMISSIONS, getPermissionNames } from "@/config/permissions";
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method !== "POST") return res.status(405).json({ message: "Method not allowed" });
|
||||
@@ -19,7 +12,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
const { apiKey, requiredPermissions } = req.body;
|
||||
if (!apiKey) return res.status(400).json({ message: "apiKey is required" });
|
||||
|
||||
const REQUIRED_PERMISSIONS: string[] = Array.isArray(requiredPermissions) ? requiredPermissions : WORKFLOW_PERMISSIONS;
|
||||
const REQUIRED_PERMISSIONS: string[] = Array.isArray(requiredPermissions) ? requiredPermissions : getPermissionNames(WORKFLOW_PERMISSIONS);
|
||||
|
||||
try {
|
||||
const keyRes = await fetch(`${ENV.IMMICH_URL}/api/api-keys/me`, {
|
||||
|
||||
@@ -22,14 +22,7 @@ import PageLayout from "@/components/layouts/PageLayout";
|
||||
import Header from "@/components/shared/Header";
|
||||
import ApiKeyGate from "@/components/shared/ApiKeyGate";
|
||||
|
||||
const IMPORT_PERMISSIONS = [
|
||||
{ name: "asset.read", description: "Check for existing assets" },
|
||||
{ name: "asset.upload", description: "Upload new assets" },
|
||||
{ name: "album.read", description: "Read album data" },
|
||||
{ name: "album.create", description: "Create new albums" },
|
||||
{ name: "album.update", description: "Add assets to albums" },
|
||||
{ name: "tag.create", description: "Tag imported assets" },
|
||||
];
|
||||
import { IMPORT_PERMISSIONS } from "@/config/permissions";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Checkbox } from "@/components/ui/checkbox";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
||||
@@ -12,6 +12,7 @@ import toast from "react-hot-toast";
|
||||
import API from "@/lib/api";
|
||||
import { useConfig } from "@/contexts/ConfigContext";
|
||||
import Link from "next/link";
|
||||
import { WORKFLOW_PERMISSIONS } from "@/config/permissions";
|
||||
|
||||
function ConnectionStatus({ label, url, icon: Icon }: { label: string; url: string; icon: any }) {
|
||||
return (
|
||||
@@ -74,7 +75,7 @@ export default function SettingsPage() {
|
||||
}
|
||||
};
|
||||
|
||||
const IMPORT_REQUIRED_PERMISSIONS = ["asset.read", "asset.upload", "album.read", "album.create", "album.update", "tag.create"];
|
||||
const IMPORT_REQUIRED_PERMISSIONS = ["asset.read", "asset.upload", "album.read", "album.create", "album.update", "tag.create", "tag.asset"];
|
||||
|
||||
const saveImportApiKey = async () => {
|
||||
if (!importApiKey.trim()) {
|
||||
@@ -269,8 +270,8 @@ export default function SettingsPage() {
|
||||
)}
|
||||
{!validationResult && (
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{["asset.read", "asset.update", "album.create", "album.update", "tag.create"].map((p) => (
|
||||
<Badge key={p} variant="outline" className="text-[10px] h-5 font-mono font-normal">{p}</Badge>
|
||||
{WORKFLOW_PERMISSIONS.map((p) => (
|
||||
<Badge key={p.name} variant="outline" className="text-[10px] h-5 font-mono font-normal">{p.name}</Badge>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -39,14 +39,7 @@ import Loader from "@/components/ui/loader";
|
||||
import API from "@/lib/api";
|
||||
import ApiKeyGate from "@/components/shared/ApiKeyGate";
|
||||
|
||||
const WORKFLOW_PERMISSIONS = [
|
||||
{ name: "asset.read", description: "Query and filter assets" },
|
||||
{ name: "asset.update", description: "Favorite, archive, update metadata" },
|
||||
{ name: "album.read", description: "Read album data" },
|
||||
{ name: "album.create", description: "Create new albums" },
|
||||
{ name: "album.update", description: "Add/remove assets from albums" },
|
||||
{ name: "tag.create", description: "Create and assign tags" },
|
||||
];
|
||||
import { WORKFLOW_PERMISSIONS } from "@/config/permissions";
|
||||
|
||||
function generateId() {
|
||||
return Math.random().toString(36).substring(2, 15);
|
||||
|
||||
Reference in New Issue
Block a user