mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-08-03 11:07:00 -04:00
implement CR feedback
This commit is contained in:
parent
8f74d83a43
commit
9682965918
@ -7,7 +7,7 @@
|
||||
</option>
|
||||
</select>
|
||||
<select v-model="s.val.area" class="form-control">
|
||||
<option v-for="a in allAreas" :value="a">
|
||||
<option v-for="a in PERMISSION_AREAS" :value="a">
|
||||
{{ a }}
|
||||
</option>
|
||||
</select>
|
||||
@ -28,6 +28,8 @@ import useConfig from '../composables/useConfig.ts';
|
||||
import useDialogue from '../composables/useDialogue.ts';
|
||||
import allLocalesRaw from '../locale/locales.ts';
|
||||
|
||||
import { PERMISSION_AREAS } from '~/src/helpers.js';
|
||||
|
||||
const allLocales = ['*'];
|
||||
for (const { code } of allLocalesRaw) {
|
||||
allLocales.push(code);
|
||||
@ -53,25 +55,7 @@ export default {
|
||||
return { locale, area };
|
||||
}),
|
||||
allLocales,
|
||||
allAreas: [
|
||||
'*',
|
||||
'basic',
|
||||
'panel',
|
||||
'users',
|
||||
'sources',
|
||||
'nouns',
|
||||
'terms',
|
||||
'inclusive',
|
||||
'census',
|
||||
'names',
|
||||
'translations',
|
||||
'code',
|
||||
'org',
|
||||
'impersonate',
|
||||
'community',
|
||||
'blog',
|
||||
'external',
|
||||
],
|
||||
PERMISSION_AREAS,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -130,7 +130,7 @@ const impersonate = async (email: string) => {
|
||||
]"
|
||||
/>
|
||||
<AdminDashboardCard
|
||||
v-show="!filterAttention && $isGranted('')"
|
||||
v-show="!filterAttention && $isGranted('panel')"
|
||||
icon="user-cog"
|
||||
link="/admin/moderation"
|
||||
header="Moderation rules"
|
||||
@ -154,7 +154,7 @@ const impersonate = async (email: string) => {
|
||||
]"
|
||||
/>
|
||||
<AdminDashboardCard
|
||||
v-show="!filterAttention && $isGranted('')"
|
||||
v-show="!filterAttention && $isGranted('panel')"
|
||||
icon="bell"
|
||||
header="Email notifications"
|
||||
>
|
||||
@ -171,7 +171,7 @@ const impersonate = async (email: string) => {
|
||||
</span>
|
||||
</AdminDashboardCard>
|
||||
<AdminDashboardCard
|
||||
v-show="!filterAttention && $isGranted('')"
|
||||
v-show="!filterAttention"
|
||||
v-if="$isGranted('users') || $isGranted('community')"
|
||||
icon="user-secret"
|
||||
header="@example"
|
||||
@ -181,19 +181,19 @@ const impersonate = async (email: string) => {
|
||||
</button>
|
||||
</AdminDashboardCard>
|
||||
<AdminDashboardCard
|
||||
v-show="!filterAttention && $isGranted('')"
|
||||
v-show="!filterAttention && $isGranted('panel')"
|
||||
icon="b:discord"
|
||||
link="https://team-discord.pronouns.page"
|
||||
header="Team Discord"
|
||||
/>
|
||||
<AdminDashboardCard
|
||||
v-show="!filterAttention && $isGranted('')"
|
||||
v-show="!filterAttention && $isGranted('panel')"
|
||||
icon="palette"
|
||||
link="/design"
|
||||
header="Design guidelines"
|
||||
/>
|
||||
<AdminDashboardCard
|
||||
v-show="!filterAttention && ($isGranted('') || $isGranted('external'))"
|
||||
v-show="!filterAttention && ($isGranted('panel') || $isGranted('external'))"
|
||||
icon="file-spreadsheet"
|
||||
link="/admin/timesheets"
|
||||
header="Volunteering timesheets"
|
||||
|
@ -7,6 +7,8 @@ import { isGrantedForUser, parseUserJwt } from '../src/helpers.ts';
|
||||
import type { Account, User } from '../src/user.ts';
|
||||
import { useMainStore } from '../store/index.ts';
|
||||
|
||||
import type { PermissionArea } from '~/src/helpers.ts';
|
||||
|
||||
declare module '#app' {
|
||||
interface NuxtApp {
|
||||
$user(): User | null;
|
||||
@ -41,7 +43,7 @@ export default defineNuxtPlugin(async (nuxtApp) => {
|
||||
}
|
||||
|
||||
const user = () => store.user;
|
||||
const isGranted = (area = '', locale = null): boolean => {
|
||||
const isGranted = (area: PermissionArea = '', locale = null): boolean => {
|
||||
return !!store.user &&
|
||||
!!store.user.authenticated &&
|
||||
isGrantedForUser(store.user, locale || config.locale, area)
|
||||
|
@ -31,7 +31,7 @@ export default defineEventHandler(async (event) => {
|
||||
conditions.push(SQL`p.locale=${locale}`);
|
||||
}
|
||||
if (query.adminsFilter) {
|
||||
conditions.push(SQL`u.roles != ''`);
|
||||
conditions.push(SQL`(u.roles != '' AND u.roles != '*-external')`);
|
||||
}
|
||||
|
||||
let conditionsSql = SQL``;
|
||||
|
3
server/global.d.ts
vendored
3
server/global.d.ts
vendored
@ -2,6 +2,7 @@ import type { LocaleDescription } from '../locale/locales.ts';
|
||||
import type { User } from '../src/user.ts';
|
||||
|
||||
import type { Database } from './db.ts';
|
||||
import type { PermissionArea } from '~/src/helpers.ts';
|
||||
|
||||
declare global {
|
||||
type GeneratorFunc<R, Args extends unknown[]> = (...args: Args) => Generator<R>;
|
||||
@ -10,7 +11,7 @@ declare global {
|
||||
export interface Request {
|
||||
rawUser: User | undefined;
|
||||
user: User | null;
|
||||
isGranted: (area?: string, locale?: string) => boolean;
|
||||
isGranted: (area?: PermissionArea, locale?: string) => boolean;
|
||||
locales: Record<string, LocaleDescription>;
|
||||
db: Database;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ async function notify() {
|
||||
return;
|
||||
}
|
||||
|
||||
const admins = await db.all('SELECT email, roles, adminNotifications FROM users WHERE roles != \'\'');
|
||||
const admins = await db.all('SELECT email, roles, adminNotifications FROM users WHERE (roles != \'\' and roles != \'*-external\')');
|
||||
|
||||
const awaitingModerationGrouped = {};
|
||||
let count = 0;
|
||||
|
@ -3,9 +3,10 @@ import type { H3Event } from 'h3';
|
||||
import { getLocale } from '~/server/data.ts';
|
||||
import jwt from '~/server/jwt.ts';
|
||||
import { isGrantedForUser } from '~/src/helpers.ts';
|
||||
import type { PermissionArea } from '~/src/helpers.ts';
|
||||
import type { User } from '~/src/user.ts';
|
||||
|
||||
export type IsGrantedFn = (area?: string, locale?: string) => boolean;
|
||||
export type IsGrantedFn = (area?: PermissionArea, locale?: string) => boolean;
|
||||
|
||||
export default async (event: H3Event) => {
|
||||
let rawUser = undefined;
|
||||
@ -22,7 +23,7 @@ export default async (event: H3Event) => {
|
||||
|
||||
const user = rawUser?.authenticated ? rawUser : null;
|
||||
const requestedLocale = getLocale(event);
|
||||
const isGranted = (area: string = '', locale = requestedLocale): boolean => {
|
||||
const isGranted = (area: PermissionArea = '', locale = requestedLocale): boolean => {
|
||||
return !!user && isGrantedForUser(user, locale, area);
|
||||
};
|
||||
return { rawUser, user, isGranted };
|
||||
|
@ -251,9 +251,31 @@ export const randomItemWeighted = <T extends WeightedItem>(array: T[]): T => {
|
||||
|
||||
export const randomNumber = (min: number, max: number): number => Math.floor(random() * (max - min + 1)) + min;
|
||||
|
||||
export const PERMISSION_AREAS = [
|
||||
'*',
|
||||
'basic',
|
||||
'panel',
|
||||
'users',
|
||||
'sources',
|
||||
'nouns',
|
||||
'terms',
|
||||
'inclusive',
|
||||
'census',
|
||||
'names',
|
||||
'translations',
|
||||
'code',
|
||||
'org',
|
||||
'impersonate',
|
||||
'community',
|
||||
'blog',
|
||||
'external',
|
||||
] as const;
|
||||
|
||||
const RESTRICTED_AREAS = ['code', 'org', 'impersonate', 'community'];
|
||||
|
||||
export const isGrantedForUser = (user: Pick<User, 'roles'>, requestedLocale: string | null, requestedArea: string = ''): boolean => {
|
||||
export type PermissionArea = typeof PERMISSION_AREAS[number] | '';
|
||||
|
||||
export const isGrantedForUser = (user: Pick<User, 'roles'>, requestedLocale: string | null, requestedArea: PermissionArea = ''): boolean => {
|
||||
if (requestedArea === '*') {
|
||||
// only super-admin
|
||||
return user.roles.split('|').includes('*');
|
||||
@ -542,8 +564,8 @@ export const deepSet = (obj: object, path: string, value: unknown): void => {
|
||||
|
||||
type AdminUser = Pick<User, 'username' | 'email' | 'roles' | 'adminNotifications'>;
|
||||
|
||||
export const findAdmins = async (db: Database, locale: string, area: string): Promise<AdminUser[]> => {
|
||||
const admins = await db.all<AdminUser>('SELECT username, email, roles, adminNotifications FROM users WHERE roles != \'\'');
|
||||
export const findAdmins = async (db: Database, locale: string, area: PermissionArea): Promise<AdminUser[]> => {
|
||||
const admins = await db.all<AdminUser>('SELECT username, email, roles, adminNotifications FROM users WHERE (roles != \'\' AND roles != \'*-external\')');
|
||||
return admins.filter((admin) => isGrantedForUser(admin, locale, area));
|
||||
};
|
||||
|
||||
|
@ -9,6 +9,8 @@ import {
|
||||
isGrantedForUser,
|
||||
} from '../src/helpers.ts';
|
||||
|
||||
import type { PermissionArea } from '~/src/helpers.ts';
|
||||
|
||||
const controlSymbols = [
|
||||
{
|
||||
description: 'slashes',
|
||||
@ -150,7 +152,7 @@ class GrantTest {
|
||||
constructor(
|
||||
public readonly givenRoles: string,
|
||||
public readonly requestedLocale: string,
|
||||
public readonly requestedArea: string,
|
||||
public readonly requestedArea: PermissionArea,
|
||||
public readonly granted: boolean,
|
||||
) {}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user