* Initial Typescript models.

* Re-add realtime data

* get distinct sessions for session metrics

* Add queries for new schema.

* Fix Typo.

* Add some api/team endpoints.

* Fix destructure error.

* Fix getWebsites call.

* Ignore typescript build errors.

* Fix enum issue.

* add clickhouse route to deleteWebsite

* Fix Website auth.

* Updated lint-staged config.

* Add permission checks.

* Add user role api.

* Fix error when updating website.

* Fix isAdmin check.  Fix Schema.

* Initial conversion to react-basics.

* Remove user/team transfer from website update.

* delete website in relational query

* Fix login secure token creation.

* Add event type to event.

* Allow user to be added to team with role.

* Updated login form.

* Add Role to TeamUser.

* Add database migration.

* Refactored permissions check. Updated redis lib.

* Feat/um 114 roles and permissions (#1683)

* Auth checkpoint.

* Merge branch 'dev' into feat/um-114-roles-and-permissions

* Add 02 migration.

* Added lib/types.

* Updated schema.

* Updated roles and permissions logic.

* Implement react-basics styles. Fix queries.

* Update website details layout.

* Add 01 migration.

* Fix admin create.

* Update react-basics.

Co-authored-by: Francis Cao <franciscao@gmail.com>
Co-authored-by: Mike Cao <mike@mikecao.com>
Co-authored-by: Mike Cao <moocao@gmail.com>
This commit is contained in:
Brian Cao 2022-12-12 19:45:38 -08:00 committed by GitHub
parent 94848cc41b
commit 8732d056dd
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
165 changed files with 3370 additions and 6268 deletions

View file

@ -0,0 +1,61 @@
import { Team } from '@prisma/client';
import { NextApiRequestQueryBody } from 'lib/types';
import { canDeleteTeam, canUpdateTeam, canViewTeam } from 'lib/auth';
import { useAuth } from 'lib/middleware';
import { NextApiResponse } from 'next';
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
import { deleteTeam, getTeam, updateTeam } from 'queries';
export interface TeamRequestQuery {
id: string;
}
export interface TeamRequestBody {
name: string;
}
export default async (
req: NextApiRequestQueryBody<TeamRequestQuery, TeamRequestBody>,
res: NextApiResponse<Team>,
) => {
await useAuth(req, res);
const {
user: { id: userId },
} = req.auth;
const { id: teamId } = req.query;
if (req.method === 'GET') {
if (!(await canViewTeam(userId, teamId))) {
return unauthorized(res);
}
const user = await getTeam({ id: teamId });
return ok(res, user);
}
if (req.method === 'POST') {
const { name } = req.body;
if (!(await canUpdateTeam(userId, teamId))) {
return unauthorized(res, 'You must be the owner of this team.');
}
const updated = await updateTeam({ name }, { id: teamId });
return ok(res, updated);
}
if (req.method === 'DELETE') {
if (!(await canDeleteTeam(userId, teamId))) {
return unauthorized(res, 'You must be the owner of this team.');
}
await deleteTeam(teamId);
return ok(res);
}
return methodNotAllowed(res);
};

View file

@ -0,0 +1,70 @@
import { NextApiRequestQueryBody } from 'lib/types';
import { canUpdateTeam, canViewTeam } from 'lib/auth';
import { useAuth } from 'lib/middleware';
import { NextApiResponse } from 'next';
import { badRequest, methodNotAllowed, ok, unauthorized } from 'next-basics';
import { createTeamUser, deleteTeamUser, getUser, getTeamUsers } from 'queries';
export interface TeamUserRequestQuery {
id: string;
}
export interface TeamUserRequestBody {
email: string;
role_id: string;
team_user_id?: string;
}
export default async (
req: NextApiRequestQueryBody<TeamUserRequestQuery, TeamUserRequestBody>,
res: NextApiResponse,
) => {
await useAuth(req, res);
const {
user: { id: userId },
} = req.auth;
const { id: teamId } = req.query;
if (req.method === 'GET') {
if (!(await canViewTeam(userId, teamId))) {
return unauthorized(res);
}
const users = await getTeamUsers(teamId);
return ok(res, users);
}
if (req.method === 'POST') {
if (!(await canUpdateTeam(userId, teamId))) {
return unauthorized(res, 'You must be the owner of this team.');
}
const { email, role_id: roleId } = req.body;
// Check for User
const user = await getUser({ username: email });
if (!user) {
return badRequest(res, 'The User does not exists.');
}
const updated = await createTeamUser(user.id, teamId, roleId);
return ok(res, updated);
}
if (req.method === 'DELETE') {
if (await canUpdateTeam(userId, teamId)) {
return unauthorized(res, 'You must be the owner of this team.');
}
const { team_user_id } = req.body;
await deleteTeamUser(team_user_id);
return ok(res);
}
return methodNotAllowed(res);
};

View file

@ -0,0 +1,39 @@
import { NextApiResponse } from 'next';
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
import { NextApiRequestQueryBody } from 'lib/types';
import { canViewTeam } from 'lib/auth';
import { useAuth } from 'lib/middleware';
import { getTeamWebsites } from 'queries/admin/team';
export interface TeamWebsiteRequestQuery {
id: string;
}
export interface TeamWebsiteRequestBody {
website_id: string;
team_website_id?: string;
}
export default async (
req: NextApiRequestQueryBody<TeamWebsiteRequestQuery, TeamWebsiteRequestBody>,
res: NextApiResponse,
) => {
await useAuth(req, res);
const {
user: { id: userId },
} = req.auth;
const { id: teamId } = req.query;
if (req.method === 'GET') {
if (await canViewTeam(userId, teamId)) {
return unauthorized(res);
}
const websites = await getTeamWebsites(teamId);
return ok(res, websites);
}
return methodNotAllowed(res);
};

47
pages/api/teams/index.ts Normal file
View file

@ -0,0 +1,47 @@
import { Team } from '@prisma/client';
import { NextApiRequestQueryBody } from 'lib/types';
import { canCreateTeam } from 'lib/auth';
import { uuid } from 'lib/crypto';
import { useAuth } from 'lib/middleware';
import { NextApiResponse } from 'next';
import { methodNotAllowed, ok, unauthorized } from 'next-basics';
import { createTeam, getUserTeams } from 'queries';
export interface TeamsRequestBody {
name: string;
}
export default async (
req: NextApiRequestQueryBody<any, TeamsRequestBody>,
res: NextApiResponse<Team[] | Team>,
) => {
await useAuth(req, res);
const {
user: { id: userId },
} = req.auth;
if (req.method === 'GET') {
const teams = await getUserTeams(userId);
return ok(res, teams);
}
if (req.method === 'POST') {
if (!(await canCreateTeam(userId))) {
return unauthorized(res);
}
const { name } = req.body;
const created = await createTeam({
id: uuid(),
name,
userId,
});
return ok(res, created);
}
return methodNotAllowed(res);
};