Spaces:
Sleeping
Sleeping
Add super basic admin feature (#1213)
Browse files
src/lib/types/User.ts
CHANGED
|
@@ -9,4 +9,5 @@ export interface User extends Timestamps {
|
|
| 9 |
email?: string;
|
| 10 |
avatarUrl: string | undefined;
|
| 11 |
hfUserId: string;
|
|
|
|
| 12 |
}
|
|
|
|
| 9 |
email?: string;
|
| 10 |
avatarUrl: string | undefined;
|
| 11 |
hfUserId: string;
|
| 12 |
+
isAdmin?: boolean;
|
| 13 |
}
|
src/routes/+layout.server.ts
CHANGED
|
@@ -193,6 +193,7 @@ export const load: LayoutServerLoad = async ({ locals, depends }) => {
|
|
| 193 |
avatarUrl: locals.user.avatarUrl,
|
| 194 |
email: locals.user.email,
|
| 195 |
logoutDisabled: locals.user.logoutDisabled,
|
|
|
|
| 196 |
},
|
| 197 |
assistant,
|
| 198 |
enableAssistants,
|
|
|
|
| 193 |
avatarUrl: locals.user.avatarUrl,
|
| 194 |
email: locals.user.email,
|
| 195 |
logoutDisabled: locals.user.logoutDisabled,
|
| 196 |
+
isAdmin: locals.user.isAdmin ?? false,
|
| 197 |
},
|
| 198 |
assistant,
|
| 199 |
enableAssistants,
|
src/routes/settings/(nav)/assistants/[assistantId]/+page.server.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { env } from "$env/dynamic/private";
|
|
| 8 |
import { z } from "zod";
|
| 9 |
import type { Assistant } from "$lib/types/Assistant";
|
| 10 |
import { logger } from "$lib/server/logger";
|
|
|
|
| 11 |
async function assistantOnlyIfAuthor(locals: App.Locals, assistantId?: string) {
|
| 12 |
const assistant = await collections.assistants.findOne({ _id: new ObjectId(assistantId) });
|
| 13 |
|
|
@@ -15,7 +16,10 @@ async function assistantOnlyIfAuthor(locals: App.Locals, assistantId?: string) {
|
|
| 15 |
throw Error("Assistant not found");
|
| 16 |
}
|
| 17 |
|
| 18 |
-
if (
|
|
|
|
|
|
|
|
|
|
| 19 |
throw Error("You are not the author of this assistant");
|
| 20 |
}
|
| 21 |
|
|
@@ -166,4 +170,29 @@ export const actions: Actions = {
|
|
| 166 |
|
| 167 |
throw redirect(302, `${base}/settings`);
|
| 168 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 169 |
};
|
|
|
|
| 8 |
import { z } from "zod";
|
| 9 |
import type { Assistant } from "$lib/types/Assistant";
|
| 10 |
import { logger } from "$lib/server/logger";
|
| 11 |
+
|
| 12 |
async function assistantOnlyIfAuthor(locals: App.Locals, assistantId?: string) {
|
| 13 |
const assistant = await collections.assistants.findOne({ _id: new ObjectId(assistantId) });
|
| 14 |
|
|
|
|
| 16 |
throw Error("Assistant not found");
|
| 17 |
}
|
| 18 |
|
| 19 |
+
if (
|
| 20 |
+
assistant.createdById.toString() !== (locals.user?._id ?? locals.sessionId).toString() &&
|
| 21 |
+
!locals.user?.isAdmin
|
| 22 |
+
) {
|
| 23 |
throw Error("You are not the author of this assistant");
|
| 24 |
}
|
| 25 |
|
|
|
|
| 170 |
|
| 171 |
throw redirect(302, `${base}/settings`);
|
| 172 |
},
|
| 173 |
+
|
| 174 |
+
unfeature: async ({ params, locals }) => {
|
| 175 |
+
if (!locals.user?.isAdmin) {
|
| 176 |
+
return fail(403, { error: true, message: "Permission denied" });
|
| 177 |
+
}
|
| 178 |
+
|
| 179 |
+
const assistant = await collections.assistants.findOne({
|
| 180 |
+
_id: new ObjectId(params.assistantId),
|
| 181 |
+
});
|
| 182 |
+
|
| 183 |
+
if (!assistant) {
|
| 184 |
+
return fail(404, { error: true, message: "Assistant not found" });
|
| 185 |
+
}
|
| 186 |
+
|
| 187 |
+
const result = await collections.assistants.updateOne(
|
| 188 |
+
{ _id: assistant._id },
|
| 189 |
+
{ $set: { featured: false } }
|
| 190 |
+
);
|
| 191 |
+
|
| 192 |
+
if (result.modifiedCount === 0) {
|
| 193 |
+
return fail(500, { error: true, message: "Failed to unfeature assistant" });
|
| 194 |
+
}
|
| 195 |
+
|
| 196 |
+
return { from: "unfeature", ok: true, message: "Assistant unfeatured" };
|
| 197 |
+
},
|
| 198 |
};
|
src/routes/settings/(nav)/assistants/[assistantId]/+page.svelte
CHANGED
|
@@ -142,6 +142,20 @@
|
|
| 142 |
>
|
| 143 |
{/if}
|
| 144 |
{/if}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 145 |
</div>
|
| 146 |
</div>
|
| 147 |
</div>
|
|
|
|
| 142 |
>
|
| 143 |
{/if}
|
| 144 |
{/if}
|
| 145 |
+
{#if data?.user?.isAdmin}
|
| 146 |
+
<form method="POST" action="?/delete" use:enhance>
|
| 147 |
+
<button type="submit" class="flex items-center text-red-600 underline">
|
| 148 |
+
<CarbonTrash class="mr-1.5 inline text-xs" />Delete</button
|
| 149 |
+
>
|
| 150 |
+
</form>
|
| 151 |
+
{#if assistant?.featured}
|
| 152 |
+
<form method="POST" action="?/unfeature" use:enhance>
|
| 153 |
+
<button type="submit" class="flex items-center text-red-600 underline">
|
| 154 |
+
<CarbonTrash class="mr-1.5 inline text-xs" />Un-feature</button
|
| 155 |
+
>
|
| 156 |
+
</form>
|
| 157 |
+
{/if}
|
| 158 |
+
{/if}
|
| 159 |
</div>
|
| 160 |
</div>
|
| 161 |
</div>
|