mirror of
https://github.com/kremalicious/umami.git
synced 2025-01-11 13:44:01 +01:00
Refactored permissions check. Updated redis lib.
This commit is contained in:
parent
1a7369e1f6
commit
a4e80ca3e5
20
lib/auth.ts
20
lib/auth.ts
@ -120,3 +120,23 @@ export async function checkPermission(req: NextApiRequestAuth, type: UmamiApi.Pe
|
||||
|
||||
return userRole.length > 0;
|
||||
}
|
||||
|
||||
export async function canViewWebsite(userId: string, websiteId: string) {
|
||||
const website = await cache.fetchWebsite(websiteId);
|
||||
|
||||
if (website.userId) {
|
||||
return userId === website.userId;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export async function canUpdateWebsite(userId: string, websiteId: string) {
|
||||
const website = await cache.fetchWebsite(websiteId);
|
||||
|
||||
if (website.userId) {
|
||||
return userId === website.userId;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { User, Website } from '@prisma/client';
|
||||
import redis, { DELETED } from 'lib/redis';
|
||||
import redis from 'lib/redis';
|
||||
import { getSession, getUser, getWebsite } from '../queries';
|
||||
|
||||
async function fetchObject(key, query) {
|
||||
@ -23,7 +23,7 @@ async function storeObject(key, data) {
|
||||
}
|
||||
|
||||
async function deleteObject(key) {
|
||||
return redis.set(key, DELETED);
|
||||
return redis.set(key, redis.DELETED);
|
||||
}
|
||||
|
||||
async function fetchWebsite(id): Promise<Website> {
|
||||
|
@ -34,6 +34,27 @@ export namespace UmamiApi {
|
||||
TeamGuest = 'Team Guest,',
|
||||
}
|
||||
}
|
||||
|
||||
export const PERMISSIONS = {
|
||||
all: 'all',
|
||||
websiteCreate: 'website:create',
|
||||
websiteUpdate: 'website:update',
|
||||
websiteDelete: 'website:delete',
|
||||
teamCreate: 'team:create',
|
||||
teamUpdate: 'team:update',
|
||||
teamDelete: 'team:delete',
|
||||
};
|
||||
|
||||
export const ROLES = {
|
||||
admin: { name: 'admin', permissions: [PERMISSIONS.all] },
|
||||
teamOwner: { name: 'team-owner', permissions: [PERMISSIONS.teamUpdate, PERMISSIONS.teamDelete] },
|
||||
teamMember: {
|
||||
name: 'team-member',
|
||||
permissions: [PERMISSIONS.websiteCreate, PERMISSIONS.websiteUpdate, PERMISSIONS.websiteDelete],
|
||||
},
|
||||
teamGuest: { name: 'team-guest' },
|
||||
};
|
||||
|
||||
export const CURRENT_VERSION = process.env.currentVersion;
|
||||
export const AUTH_TOKEN = 'umami.auth';
|
||||
export const LOCALE_CONFIG = 'umami.locale';
|
||||
@ -57,9 +78,6 @@ export const DEFAULT_WEBSITE_LIMIT = 10;
|
||||
export const REALTIME_RANGE = 30;
|
||||
export const REALTIME_INTERVAL = 3000;
|
||||
|
||||
export const TYPE_WEBSITE = 'website';
|
||||
export const TYPE_USER = 'user';
|
||||
|
||||
export const THEME_COLORS = {
|
||||
light: {
|
||||
primary: '#2680eb',
|
||||
|
10
lib/redis.js
10
lib/redis.js
@ -3,16 +3,18 @@ import debug from 'debug';
|
||||
|
||||
const log = debug('umami:redis');
|
||||
const REDIS = Symbol();
|
||||
const DELETED = 'DELETED';
|
||||
|
||||
let redis;
|
||||
const enabled = Boolean(process.env.REDIS_URL);
|
||||
const url = process.env.REDIS_URL;
|
||||
const enabled = Boolean(url);
|
||||
|
||||
async function getClient() {
|
||||
if (!process.env.REDIS_URL) {
|
||||
if (!enabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const client = createClient({ url: process.env.REDIS_URL });
|
||||
const client = createClient({ url });
|
||||
client.on('error', err => log(err));
|
||||
await client.connect();
|
||||
|
||||
@ -59,4 +61,4 @@ async function connect() {
|
||||
return redis;
|
||||
}
|
||||
|
||||
export default { enabled, client: redis, log, connect, get, set, del };
|
||||
export default { enabled, client: redis, log, connect, get, set, del, DELETED };
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { Website } from 'interface/api/models';
|
||||
import { NextApiRequestQueryBody } from 'interface/api/nextApi';
|
||||
import { allowQuery } from 'lib/auth';
|
||||
import { UmamiApi } from 'lib/constants';
|
||||
import { canViewWebsite, canUpdateWebsite } from 'lib/auth';
|
||||
import { useAuth, useCors } from 'lib/middleware';
|
||||
import { NextApiResponse } from 'next';
|
||||
import { methodNotAllowed, ok, serverError, unauthorized } from 'next-basics';
|
||||
@ -26,17 +25,21 @@ export default async (
|
||||
|
||||
const { id: websiteId } = req.query;
|
||||
|
||||
if (!(await allowQuery(req, UmamiApi.AuthType.Website))) {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
if (req.method === 'GET') {
|
||||
if (!(await canViewWebsite(req.auth.user.id, websiteId))) {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
const website = await getWebsite({ id: websiteId });
|
||||
|
||||
return ok(res, website);
|
||||
}
|
||||
|
||||
if (req.method === 'POST') {
|
||||
if (!(await canUpdateWebsite(req.auth.user.id, websiteId))) {
|
||||
return unauthorized(res);
|
||||
}
|
||||
|
||||
const { name, domain, shareId } = req.body;
|
||||
|
||||
try {
|
||||
|
Loading…
Reference in New Issue
Block a user