fix: member permissions now works correctly

This commit is contained in:
Jordan Knott 2020-09-19 17:26:02 -05:00
parent 0366b4c7f7
commit 0d4fb6a0d0
29 changed files with 604 additions and 462 deletions

View File

@ -309,7 +309,7 @@ const Details: React.FC<DetailsProps> = ({
task={data.findTask}
onChecklistDrop={checklist => {
updateTaskChecklistLocation({
variables: { checklistID: checklist.id, position: checklist.position },
variables: { taskChecklistID: checklist.id, position: checklist.position },
optimisticResponse: {
__typename: 'Mutation',
@ -324,20 +324,24 @@ const Details: React.FC<DetailsProps> = ({
},
});
}}
onChecklistItemDrop={(prevChecklistID, checklistID, checklistItem) => {
onChecklistItemDrop={(prevChecklistID, taskChecklistID, checklistItem) => {
updateTaskChecklistItemLocation({
variables: { checklistID, checklistItemID: checklistItem.id, position: checklistItem.position },
variables: {
taskChecklistID,
taskChecklistItemID: checklistItem.id,
position: checklistItem.position,
},
optimisticResponse: {
__typename: 'Mutation',
updateTaskChecklistItemLocation: {
__typename: 'UpdateTaskChecklistItemLocationPayload',
prevChecklistID,
checklistID,
taskChecklistID,
checklistItem: {
__typename: 'TaskChecklistItem',
position: checklistItem.position,
id: checklistItem.id,
taskChecklistID: checklistID,
taskChecklistID,
},
},
},

View File

@ -135,7 +135,26 @@ const Project = () => {
const [value, setValue] = useStateWithLocalStorage(CARD_LABEL_VARIANT_STORAGE_KEY);
const [updateProjectMemberRole] = useUpdateProjectMemberRoleMutation();
const [deleteTask] = useDeleteTaskMutation();
const [deleteTask] = useDeleteTaskMutation({
update: (client, resp) =>
updateApolloCache<FindProjectQuery>(
client,
FindProjectDocument,
cache =>
produce(cache, draftCache => {
const taskGroupIdx = draftCache.findProject.taskGroups.findIndex(
tg => tg.tasks.findIndex(t => t.id === resp.data.deleteTask.taskID) !== -1,
);
if (taskGroupIdx !== -1) {
draftCache.findProject.taskGroups[taskGroupIdx].tasks = cache.findProject.taskGroups[
taskGroupIdx
].tasks.filter(t => t.id !== resp.data.deleteTask.taskID);
}
}),
{ projectID },
),
});
const [updateTaskName] = useUpdateTaskNameMutation();
@ -284,6 +303,7 @@ const Project = () => {
}}
onDeleteTask={deletedTask => {
deleteTask({ variables: { taskID: deletedTask.id } });
history.push(`${match.url}/board`);
}}
onOpenAddLabelPopup={(task, $targetRef) => {
taskLabelsRef.current = task.labels;

View File

@ -209,7 +209,10 @@ export enum ObjectType {
Org = 'ORG',
Team = 'TEAM',
Project = 'PROJECT',
Task = 'TASK'
Task = 'TASK',
TaskGroup = 'TASK_GROUP',
TaskChecklist = 'TASK_CHECKLIST',
TaskChecklistItem = 'TASK_CHECKLIST_ITEM'
}
export type Query = {
@ -588,7 +591,7 @@ export type ProjectsFilter = {
};
export type FindUser = {
userId: Scalars['String'];
userID: Scalars['UUID'];
};
export type FindProject = {
@ -722,7 +725,7 @@ export type UpdateProjectMemberRolePayload = {
};
export type NewTask = {
taskGroupID: Scalars['String'];
taskGroupID: Scalars['UUID'];
name: Scalars['String'];
position: Scalars['Float'];
};
@ -765,34 +768,34 @@ export type NewTaskLocation = {
};
export type DeleteTaskInput = {
taskID: Scalars['String'];
taskID: Scalars['UUID'];
};
export type DeleteTaskPayload = {
__typename?: 'DeleteTaskPayload';
taskID: Scalars['String'];
taskID: Scalars['UUID'];
};
export type UpdateTaskName = {
taskID: Scalars['String'];
taskID: Scalars['UUID'];
name: Scalars['String'];
};
export type UpdateTaskChecklistItemLocation = {
checklistID: Scalars['UUID'];
checklistItemID: Scalars['UUID'];
taskChecklistID: Scalars['UUID'];
taskChecklistItemID: Scalars['UUID'];
position: Scalars['Float'];
};
export type UpdateTaskChecklistItemLocationPayload = {
__typename?: 'UpdateTaskChecklistItemLocationPayload';
checklistID: Scalars['UUID'];
taskChecklistID: Scalars['UUID'];
prevChecklistID: Scalars['UUID'];
checklistItem: TaskChecklistItem;
};
export type UpdateTaskChecklistLocation = {
checklistID: Scalars['UUID'];
taskChecklistID: Scalars['UUID'];
position: Scalars['Float'];
};
@ -908,7 +911,7 @@ export type DeleteTaskGroupPayload = {
};
export type NewTaskGroup = {
projectID: Scalars['String'];
projectID: Scalars['UUID'];
name: Scalars['String'];
position: Scalars['Float'];
};
@ -919,6 +922,7 @@ export type AddTaskLabelInput = {
};
export type RemoveTaskLabelInput = {
taskID: Scalars['UUID'];
taskLabelID: Scalars['UUID'];
};
@ -1020,7 +1024,7 @@ export type UpdateUserRolePayload = {
};
export type NewRefreshToken = {
userId: Scalars['String'];
userID: Scalars['UUID'];
};
export type NewUserAccount = {
@ -1033,7 +1037,7 @@ export type NewUserAccount = {
};
export type LogoutUser = {
userID: Scalars['String'];
userID: Scalars['UUID'];
};
export type DeleteUserAccount = {
@ -1119,7 +1123,7 @@ export type CreateProjectLabelMutation = (
);
export type CreateTaskGroupMutationVariables = {
projectID: Scalars['String'];
projectID: Scalars['UUID'];
name: Scalars['String'];
position: Scalars['Float'];
};
@ -1147,7 +1151,7 @@ export type DeleteProjectLabelMutation = (
);
export type DeleteTaskMutationVariables = {
taskID: Scalars['String'];
taskID: Scalars['UUID'];
};
@ -1472,7 +1476,7 @@ export type UpdateProjectMemberRoleMutation = (
);
export type CreateTaskMutationVariables = {
taskGroupID: Scalars['String'];
taskGroupID: Scalars['UUID'];
name: Scalars['String'];
position: Scalars['Float'];
};
@ -1583,8 +1587,8 @@ export type SetTaskCompleteMutation = (
);
export type UpdateTaskChecklistItemLocationMutationVariables = {
checklistID: Scalars['UUID'];
checklistItemID: Scalars['UUID'];
taskChecklistID: Scalars['UUID'];
taskChecklistItemID: Scalars['UUID'];
position: Scalars['Float'];
};
@ -1593,7 +1597,7 @@ export type UpdateTaskChecklistItemLocationMutation = (
{ __typename?: 'Mutation' }
& { updateTaskChecklistItemLocation: (
{ __typename?: 'UpdateTaskChecklistItemLocationPayload' }
& Pick<UpdateTaskChecklistItemLocationPayload, 'checklistID' | 'prevChecklistID'>
& Pick<UpdateTaskChecklistItemLocationPayload, 'taskChecklistID' | 'prevChecklistID'>
& { checklistItem: (
{ __typename?: 'TaskChecklistItem' }
& Pick<TaskChecklistItem, 'id' | 'taskChecklistID' | 'position'>
@ -1616,7 +1620,7 @@ export type UpdateTaskChecklistItemNameMutation = (
);
export type UpdateTaskChecklistLocationMutationVariables = {
checklistID: Scalars['UUID'];
taskChecklistID: Scalars['UUID'];
position: Scalars['Float'];
};
@ -2072,7 +2076,7 @@ export type UpdateTaskLocationMutation = (
);
export type UpdateTaskNameMutationVariables = {
taskID: Scalars['String'];
taskID: Scalars['UUID'];
name: Scalars['String'];
};
@ -2442,7 +2446,7 @@ export type CreateProjectLabelMutationHookResult = ReturnType<typeof useCreatePr
export type CreateProjectLabelMutationResult = ApolloReactCommon.MutationResult<CreateProjectLabelMutation>;
export type CreateProjectLabelMutationOptions = ApolloReactCommon.BaseMutationOptions<CreateProjectLabelMutation, CreateProjectLabelMutationVariables>;
export const CreateTaskGroupDocument = gql`
mutation createTaskGroup($projectID: String!, $name: String!, $position: Float!) {
mutation createTaskGroup($projectID: UUID!, $name: String!, $position: Float!) {
createTaskGroup(input: {projectID: $projectID, name: $name, position: $position}) {
id
name
@ -2510,7 +2514,7 @@ export type DeleteProjectLabelMutationHookResult = ReturnType<typeof useDeletePr
export type DeleteProjectLabelMutationResult = ApolloReactCommon.MutationResult<DeleteProjectLabelMutation>;
export type DeleteProjectLabelMutationOptions = ApolloReactCommon.BaseMutationOptions<DeleteProjectLabelMutation, DeleteProjectLabelMutationVariables>;
export const DeleteTaskDocument = gql`
mutation deleteTask($taskID: String!) {
mutation deleteTask($taskID: UUID!) {
deleteTask(input: {taskID: $taskID}) {
taskID
}
@ -3044,7 +3048,7 @@ export type UpdateProjectMemberRoleMutationHookResult = ReturnType<typeof useUpd
export type UpdateProjectMemberRoleMutationResult = ApolloReactCommon.MutationResult<UpdateProjectMemberRoleMutation>;
export type UpdateProjectMemberRoleMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateProjectMemberRoleMutation, UpdateProjectMemberRoleMutationVariables>;
export const CreateTaskDocument = gql`
mutation createTask($taskGroupID: String!, $name: String!, $position: Float!) {
mutation createTask($taskGroupID: UUID!, $name: String!, $position: Float!) {
createTask(input: {taskGroupID: $taskGroupID, name: $name, position: $position}) {
...TaskFields
}
@ -3297,9 +3301,9 @@ export type SetTaskCompleteMutationHookResult = ReturnType<typeof useSetTaskComp
export type SetTaskCompleteMutationResult = ApolloReactCommon.MutationResult<SetTaskCompleteMutation>;
export type SetTaskCompleteMutationOptions = ApolloReactCommon.BaseMutationOptions<SetTaskCompleteMutation, SetTaskCompleteMutationVariables>;
export const UpdateTaskChecklistItemLocationDocument = gql`
mutation updateTaskChecklistItemLocation($checklistID: UUID!, $checklistItemID: UUID!, $position: Float!) {
updateTaskChecklistItemLocation(input: {checklistID: $checklistID, checklistItemID: $checklistItemID, position: $position}) {
checklistID
mutation updateTaskChecklistItemLocation($taskChecklistID: UUID!, $taskChecklistItemID: UUID!, $position: Float!) {
updateTaskChecklistItemLocation(input: {taskChecklistID: $taskChecklistID, taskChecklistItemID: $taskChecklistItemID, position: $position}) {
taskChecklistID
prevChecklistID
checklistItem {
id
@ -3324,8 +3328,8 @@ export type UpdateTaskChecklistItemLocationMutationFn = ApolloReactCommon.Mutati
* @example
* const [updateTaskChecklistItemLocationMutation, { data, loading, error }] = useUpdateTaskChecklistItemLocationMutation({
* variables: {
* checklistID: // value for 'checklistID'
* checklistItemID: // value for 'checklistItemID'
* taskChecklistID: // value for 'taskChecklistID'
* taskChecklistItemID: // value for 'taskChecklistItemID'
* position: // value for 'position'
* },
* });
@ -3371,8 +3375,8 @@ export type UpdateTaskChecklistItemNameMutationHookResult = ReturnType<typeof us
export type UpdateTaskChecklistItemNameMutationResult = ApolloReactCommon.MutationResult<UpdateTaskChecklistItemNameMutation>;
export type UpdateTaskChecklistItemNameMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateTaskChecklistItemNameMutation, UpdateTaskChecklistItemNameMutationVariables>;
export const UpdateTaskChecklistLocationDocument = gql`
mutation updateTaskChecklistLocation($checklistID: UUID!, $position: Float!) {
updateTaskChecklistLocation(input: {checklistID: $checklistID, position: $position}) {
mutation updateTaskChecklistLocation($taskChecklistID: UUID!, $position: Float!) {
updateTaskChecklistLocation(input: {taskChecklistID: $taskChecklistID, position: $position}) {
checklist {
id
position
@ -3395,7 +3399,7 @@ export type UpdateTaskChecklistLocationMutationFn = ApolloReactCommon.MutationFu
* @example
* const [updateTaskChecklistLocationMutation, { data, loading, error }] = useUpdateTaskChecklistLocationMutation({
* variables: {
* checklistID: // value for 'checklistID'
* taskChecklistID: // value for 'taskChecklistID'
* position: // value for 'position'
* },
* });
@ -4275,7 +4279,7 @@ export type UpdateTaskLocationMutationHookResult = ReturnType<typeof useUpdateTa
export type UpdateTaskLocationMutationResult = ApolloReactCommon.MutationResult<UpdateTaskLocationMutation>;
export type UpdateTaskLocationMutationOptions = ApolloReactCommon.BaseMutationOptions<UpdateTaskLocationMutation, UpdateTaskLocationMutationVariables>;
export const UpdateTaskNameDocument = gql`
mutation updateTaskName($taskID: String!, $name: String!) {
mutation updateTaskName($taskID: UUID!, $name: String!) {
updateTaskName(input: {taskID: $taskID, name: $name}) {
id
name

View File

@ -1,4 +1,4 @@
mutation createTaskGroup( $projectID: String!, $name: String!, $position: Float! ) {
mutation createTaskGroup( $projectID: UUID!, $name: String!, $position: Float! ) {
createTaskGroup(
input: { projectID: $projectID, name: $name, position: $position }
) {

View File

@ -1,4 +1,4 @@
mutation deleteTask($taskID: String!) {
mutation deleteTask($taskID: UUID!) {
deleteTask(input: { taskID: $taskID }) {
taskID
}

View File

@ -2,7 +2,7 @@ import gql from 'graphql-tag';
import TASK_FRAGMENT from '../fragments/task';
const CREATE_TASK_MUTATION = gql`
mutation createTask($taskGroupID: String!, $name: String!, $position: Float!) {
mutation createTask($taskGroupID: UUID!, $name: String!, $position: Float!) {
createTask(input: { taskGroupID: $taskGroupID, name: $name, position: $position }) {
...TaskFields
}

View File

@ -1,11 +1,11 @@
import gql from 'graphql-tag';
const UPDATE_TASK_CHECKLIST_ITEM_LOCATION_MUTATION = gql`
mutation updateTaskChecklistItemLocation($checklistID: UUID!, $checklistItemID: UUID!, $position: Float!) {
mutation updateTaskChecklistItemLocation($taskChecklistID: UUID!, $taskChecklistItemID: UUID!, $position: Float!) {
updateTaskChecklistItemLocation(
input: { checklistID: $checklistID, checklistItemID: $checklistItemID, position: $position }
input: { taskChecklistID: $taskChecklistID, taskChecklistItemID: $taskChecklistItemID, position: $position }
) {
checklistID
taskChecklistID
prevChecklistID
checklistItem {
id

View File

@ -1,8 +1,8 @@
import gql from 'graphql-tag';
const UPDATE_TASK_CHECKLIST_LOCATION_MUTATION = gql`
mutation updateTaskChecklistLocation($checklistID: UUID!, $position: Float!) {
updateTaskChecklistLocation(input: { checklistID: $checklistID, position: $position }) {
mutation updateTaskChecklistLocation($taskChecklistID: UUID!, $position: Float!) {
updateTaskChecklistLocation(input: { taskChecklistID: $taskChecklistID, position: $position }) {
checklist {
id
position

View File

@ -1,4 +1,4 @@
mutation updateTaskName($taskID: String!, $name: String!) {
mutation updateTaskName($taskID: UUID!, $name: String!) {
updateTaskName(input: { taskID: $taskID, name: $name }) {
id
name

View File

@ -2,9 +2,10 @@ package commands
import (
"fmt"
"time"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"time"
"github.com/RichardKnop/machinery/v1"
"github.com/RichardKnop/machinery/v1/config"

View File

@ -64,6 +64,9 @@ type Querier interface {
GetNotificationForNotificationID(ctx context.Context, notificationID uuid.UUID) (GetNotificationForNotificationIDRow, error)
GetProjectByID(ctx context.Context, projectID uuid.UUID) (Project, error)
GetProjectIDForTask(ctx context.Context, taskID uuid.UUID) (uuid.UUID, error)
GetProjectIDForTaskChecklist(ctx context.Context, taskChecklistID uuid.UUID) (uuid.UUID, error)
GetProjectIDForTaskChecklistItem(ctx context.Context, taskChecklistItemID uuid.UUID) (uuid.UUID, error)
GetProjectIDForTaskGroup(ctx context.Context, taskGroupID uuid.UUID) (uuid.UUID, error)
GetProjectLabelByID(ctx context.Context, projectLabelID uuid.UUID) (ProjectLabel, error)
GetProjectLabelsForProject(ctx context.Context, projectID uuid.UUID) ([]ProjectLabel, error)
GetProjectMembersForProjectID(ctx context.Context, projectID uuid.UUID) ([]ProjectMember, error)

View File

@ -25,4 +25,3 @@ WHERE n.notification_id = $1;
-- name: CreateNotification :one
INSERT INTO notification(notification_object_id, notifier_id)
VALUES ($1, $2) RETURNING *;

View File

@ -41,3 +41,16 @@ UPDATE task_checklist SET position = $2 WHERE task_checklist_id = $1 RETURNING *
-- name: UpdateTaskChecklistItemLocation :one
UPDATE task_checklist_item SET position = $2, task_checklist_id = $3 WHERE task_checklist_item_id = $1 RETURNING *;
-- name: GetProjectIDForTaskChecklist :one
SELECT project_id FROM task_checklist
INNER JOIN task ON task.task_id = task_checklist.task_id
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
WHERE task_checklist.task_checklist_id = $1;
-- name: GetProjectIDForTaskChecklistItem :one
SELECT project_id FROM task_checklist_item AS tci
INNER JOIN task_checklist ON task_checklist.task_checklist_id = tci.task_checklist_id
INNER JOIN task ON task.task_id = task_checklist.task_id
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
WHERE tci.task_checklist_item_id = $1;

View File

@ -5,6 +5,9 @@ INSERT INTO task_group (project_id, created_at, name, position)
-- name: GetTaskGroupsForProject :many
SELECT * FROM task_group WHERE project_id = $1;
-- name: GetProjectIDForTaskGroup :one
SELECT project_id from task_group WHERE task_group_id = $1;
-- name: GetAllTaskGroups :many
SELECT * FROM task_group;

View File

@ -90,6 +90,35 @@ func (q *Queries) DeleteTaskChecklistItem(ctx context.Context, taskChecklistItem
return err
}
const getProjectIDForTaskChecklist = `-- name: GetProjectIDForTaskChecklist :one
SELECT project_id FROM task_checklist
INNER JOIN task ON task.task_id = task_checklist.task_id
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
WHERE task_checklist.task_checklist_id = $1
`
func (q *Queries) GetProjectIDForTaskChecklist(ctx context.Context, taskChecklistID uuid.UUID) (uuid.UUID, error) {
row := q.db.QueryRowContext(ctx, getProjectIDForTaskChecklist, taskChecklistID)
var project_id uuid.UUID
err := row.Scan(&project_id)
return project_id, err
}
const getProjectIDForTaskChecklistItem = `-- name: GetProjectIDForTaskChecklistItem :one
SELECT project_id FROM task_checklist_item AS tci
INNER JOIN task_checklist ON task_checklist.task_checklist_id = tci.task_checklist_id
INNER JOIN task ON task.task_id = task_checklist.task_id
INNER JOIN task_group ON task_group.task_group_id = task.task_group_id
WHERE tci.task_checklist_item_id = $1
`
func (q *Queries) GetProjectIDForTaskChecklistItem(ctx context.Context, taskChecklistItemID uuid.UUID) (uuid.UUID, error) {
row := q.db.QueryRowContext(ctx, getProjectIDForTaskChecklistItem, taskChecklistItemID)
var project_id uuid.UUID
err := row.Scan(&project_id)
return project_id, err
}
const getTaskChecklistByID = `-- name: GetTaskChecklistByID :one
SELECT task_checklist_id, task_id, created_at, name, position FROM task_checklist WHERE task_checklist_id = $1
`

View File

@ -85,6 +85,17 @@ func (q *Queries) GetAllTaskGroups(ctx context.Context) ([]TaskGroup, error) {
return items, nil
}
const getProjectIDForTaskGroup = `-- name: GetProjectIDForTaskGroup :one
SELECT project_id from task_group WHERE task_group_id = $1
`
func (q *Queries) GetProjectIDForTaskGroup(ctx context.Context, taskGroupID uuid.UUID) (uuid.UUID, error) {
row := q.db.QueryRowContext(ctx, getProjectIDForTaskGroup, taskGroupID)
var project_id uuid.UUID
err := row.Scan(&project_id)
return project_id, err
}
const getTaskGroupByID = `-- name: GetTaskGroupByID :one
SELECT task_group_id, project_id, created_at, name, position FROM task_group WHERE task_group_id = $1
`

File diff suppressed because it is too large Load Diff

View File

@ -51,31 +51,56 @@ func NewHandler(repo db.Repository) http.Handler {
fieldName = "TeamID"
case ObjectTypeTask:
fieldName = "TaskID"
case ObjectTypeTaskGroup:
fieldName = "TaskGroupID"
case ObjectTypeTaskChecklist:
fieldName = "TaskChecklistID"
case ObjectTypeTaskChecklistItem:
fieldName = "TaskChecklistItemID"
default:
fieldName = "ProjectID"
}
log.WithFields(log.Fields{"typeArg": typeArg, "fieldName": fieldName}).Info("getting field by name")
subjectID, ok = val.FieldByName(fieldName).Interface().(uuid.UUID)
subjectField := val.FieldByName(fieldName)
if !subjectField.IsValid() {
log.Error("subject field name does not exist on input type")
return nil, errors.New("subject field name does not exist on input type")
}
subjectID, ok = subjectField.Interface().(uuid.UUID)
if !ok {
log.Error("error while casting subject UUID")
return nil, errors.New("error while casting subject uuid")
}
var err error
if level == ActionLevelProject {
log.WithFields(log.Fields{"subjectID": subjectID}).Info("fetching subject ID by typeArg")
if typeArg == ObjectTypeTask {
log.WithFields(log.Fields{"subjectID": subjectID}).Info("fetching project ID using task ID")
subjectID, err = repo.GetProjectIDForTask(ctx, subjectID)
if err != nil {
return nil, err
}
}
roles, err := GetProjectRoles(ctx, repo, subjectID)
if typeArg == ObjectTypeTaskGroup {
subjectID, err = repo.GetProjectIDForTaskGroup(ctx, subjectID)
}
if typeArg == ObjectTypeTaskChecklist {
subjectID, err = repo.GetProjectIDForTaskChecklist(ctx, subjectID)
}
if typeArg == ObjectTypeTaskChecklistItem {
subjectID, err = repo.GetProjectIDForTaskChecklistItem(ctx, subjectID)
}
if err != nil {
log.WithError(err).Error("error while getting subject ID")
return nil, err
}
if roles.TeamRole == "admin" || roles.ProjectRole == "admin" {
log.WithFields(log.Fields{"teamRole": roles.TeamRole, "projectRole": roles.ProjectRole}).Info("is team or project role")
return next(ctx)
projectRoles, err := GetProjectRoles(ctx, repo, subjectID)
if err != nil {
log.WithError(err).Error("error while getting project roles")
return nil, err
}
for _, validRole := range roles {
if GetRoleLevel(projectRoles.TeamRole) == validRole || GetRoleLevel(projectRoles.ProjectRole) == validRole {
log.WithFields(log.Fields{"teamRole": projectRoles.TeamRole, "projectRole": projectRoles.ProjectRole}).Info("is team or project role")
return next(ctx)
}
}
return nil, errors.New("must be a team or project admin")
} else if level == ActionLevelTeam {
@ -85,10 +110,13 @@ func NewHandler(repo db.Repository) http.Handler {
}
role, err := repo.GetTeamRoleForUserID(ctx, db.GetTeamRoleForUserIDParams{UserID: userID, TeamID: subjectID})
if err != nil {
log.WithError(err).Error("error while getting team roles for user ID")
return nil, err
}
if role.RoleCode == "admin" {
return next(ctx)
for _, validRole := range roles {
if GetRoleLevel(role.RoleCode) == validRole || GetRoleLevel(role.RoleCode) == validRole {
return next(ctx)
}
}
return nil, errors.New("must be a team admin")
@ -156,6 +184,14 @@ func GetProjectRoles(ctx context.Context, r db.Repository, projectID uuid.UUID)
return r.GetUserRolesForProject(ctx, db.GetUserRolesForProjectParams{UserID: userID, ProjectID: projectID})
}
// GetRoleLevel converts a role level string to a RoleLevel type
func GetRoleLevel(r string) RoleLevel {
if r == RoleLevelAdmin.String() {
return RoleLevelAdmin
}
return RoleLevelMember
}
// ConvertToRoleCode converts a role code string to a RoleCode type
func ConvertToRoleCode(r string) RoleCode {
if r == RoleCodeAdmin.String() {

View File

@ -121,11 +121,11 @@ type DeleteTaskGroupTasksPayload struct {
}
type DeleteTaskInput struct {
TaskID string `json:"taskID"`
TaskID uuid.UUID `json:"taskID"`
}
type DeleteTaskPayload struct {
TaskID string `json:"taskID"`
TaskID uuid.UUID `json:"taskID"`
}
type DeleteTeam struct {
@ -184,11 +184,11 @@ type FindTeam struct {
}
type FindUser struct {
UserID string `json:"userId"`
UserID uuid.UUID `json:"userID"`
}
type LogoutUser struct {
UserID string `json:"userID"`
UserID uuid.UUID `json:"userID"`
}
type MePayload struct {
@ -225,19 +225,19 @@ type NewProjectLabel struct {
}
type NewRefreshToken struct {
UserID string `json:"userId"`
UserID uuid.UUID `json:"userID"`
}
type NewTask struct {
TaskGroupID string `json:"taskGroupID"`
Name string `json:"name"`
Position float64 `json:"position"`
TaskGroupID uuid.UUID `json:"taskGroupID"`
Name string `json:"name"`
Position float64 `json:"position"`
}
type NewTaskGroup struct {
ProjectID string `json:"projectID"`
Name string `json:"name"`
Position float64 `json:"position"`
ProjectID uuid.UUID `json:"projectID"`
Name string `json:"name"`
Position float64 `json:"position"`
}
type NewTaskGroupLocation struct {
@ -303,6 +303,7 @@ type ProjectsFilter struct {
}
type RemoveTaskLabelInput struct {
TaskID uuid.UUID `json:"taskID"`
TaskLabelID uuid.UUID `json:"taskLabelID"`
}
@ -388,13 +389,13 @@ type UpdateProjectName struct {
}
type UpdateTaskChecklistItemLocation struct {
ChecklistID uuid.UUID `json:"checklistID"`
ChecklistItemID uuid.UUID `json:"checklistItemID"`
Position float64 `json:"position"`
TaskChecklistID uuid.UUID `json:"taskChecklistID"`
TaskChecklistItemID uuid.UUID `json:"taskChecklistItemID"`
Position float64 `json:"position"`
}
type UpdateTaskChecklistItemLocationPayload struct {
ChecklistID uuid.UUID `json:"checklistID"`
TaskChecklistID uuid.UUID `json:"taskChecklistID"`
PrevChecklistID uuid.UUID `json:"prevChecklistID"`
ChecklistItem *db.TaskChecklistItem `json:"checklistItem"`
}
@ -405,8 +406,8 @@ type UpdateTaskChecklistItemName struct {
}
type UpdateTaskChecklistLocation struct {
ChecklistID uuid.UUID `json:"checklistID"`
Position float64 `json:"position"`
TaskChecklistID uuid.UUID `json:"taskChecklistID"`
Position float64 `json:"position"`
}
type UpdateTaskChecklistLocationPayload struct {
@ -439,8 +440,8 @@ type UpdateTaskLocationPayload struct {
}
type UpdateTaskName struct {
TaskID string `json:"taskID"`
Name string `json:"name"`
TaskID uuid.UUID `json:"taskID"`
Name string `json:"name"`
}
type UpdateTeamMemberRole struct {
@ -648,10 +649,13 @@ func (e EntityType) MarshalGQL(w io.Writer) {
type ObjectType string
const (
ObjectTypeOrg ObjectType = "ORG"
ObjectTypeTeam ObjectType = "TEAM"
ObjectTypeProject ObjectType = "PROJECT"
ObjectTypeTask ObjectType = "TASK"
ObjectTypeOrg ObjectType = "ORG"
ObjectTypeTeam ObjectType = "TEAM"
ObjectTypeProject ObjectType = "PROJECT"
ObjectTypeTask ObjectType = "TASK"
ObjectTypeTaskGroup ObjectType = "TASK_GROUP"
ObjectTypeTaskChecklist ObjectType = "TASK_CHECKLIST"
ObjectTypeTaskChecklistItem ObjectType = "TASK_CHECKLIST_ITEM"
)
var AllObjectType = []ObjectType{
@ -659,11 +663,14 @@ var AllObjectType = []ObjectType{
ObjectTypeTeam,
ObjectTypeProject,
ObjectTypeTask,
ObjectTypeTaskGroup,
ObjectTypeTaskChecklist,
ObjectTypeTaskChecklistItem,
}
func (e ObjectType) IsValid() bool {
switch e {
case ObjectTypeOrg, ObjectTypeTeam, ObjectTypeProject, ObjectTypeTask:
case ObjectTypeOrg, ObjectTypeTeam, ObjectTypeProject, ObjectTypeTask, ObjectTypeTaskGroup, ObjectTypeTaskChecklist, ObjectTypeTaskChecklistItem:
return true
}
return false

View File

@ -174,6 +174,9 @@ enum ObjectType {
TEAM
PROJECT
TASK
TASK_GROUP
TASK_CHECKLIST
TASK_CHECKLIST_ITEM
}
directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
@ -215,7 +218,7 @@ input ProjectsFilter {
}
input FindUser {
userId: String!
userID: UUID!
}
input FindProject {
@ -297,15 +300,15 @@ type DeleteProjectPayload {
extend type Mutation {
createProjectLabel(input: NewProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
deleteProjectLabel(input: DeleteProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabel(input: UpdateProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabelName(input: UpdateProjectLabelName!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabelColor(input: UpdateProjectLabelColor!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
}
input NewProjectLabel {
@ -377,29 +380,29 @@ type UpdateProjectMemberRolePayload {
extend type Mutation {
createTask(input: NewTask!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTask(input: DeleteTaskInput!):
DeleteTaskPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DeleteTaskPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskDescription(input: UpdateTaskDescriptionInput!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskLocation(input: NewTaskLocation!):
UpdateTaskLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
UpdateTaskLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskName(input: UpdateTaskName!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
setTaskComplete(input: SetTaskComplete!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskDueDate(input: UpdateTaskDueDate!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
assignTask(input: AssignTaskInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
unassignTask(input: UnassignTaskInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
}
input NewTask {
taskGroupID: String!
taskGroupID: UUID!
name: String!
position: Float!
}
@ -441,54 +444,55 @@ input NewTaskLocation {
}
input DeleteTaskInput {
taskID: String!
taskID: UUID!
}
type DeleteTaskPayload {
taskID: String!
taskID: UUID!
}
input UpdateTaskName {
taskID: String!
taskID: UUID!
name: String!
}
extend type Mutation {
createTaskChecklist(input: CreateTaskChecklist!):
TaskChecklist! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskChecklist! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
deleteTaskChecklist(input: DeleteTaskChecklist!):
DeleteTaskChecklistPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DeleteTaskChecklistPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistName(input: UpdateTaskChecklistName!):
TaskChecklist! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskChecklist! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
createTaskChecklistItem(input: CreateTaskChecklistItem!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!):
DeleteTaskChecklistItemPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistLocation(input: UpdateTaskChecklistLocation!):
UpdateTaskChecklistLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
UpdateTaskChecklistLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!):
TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!):
TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!):
DeleteTaskChecklistItemPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
updateTaskChecklistItemLocation(input: UpdateTaskChecklistItemLocation!):
UpdateTaskChecklistItemLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
UpdateTaskChecklistItemLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
}
input UpdateTaskChecklistItemLocation {
checklistID: UUID!
checklistItemID: UUID!
taskChecklistID: UUID!
taskChecklistItemID: UUID!
position: Float!
}
type UpdateTaskChecklistItemLocationPayload {
checklistID: UUID!
taskChecklistID: UUID!
prevChecklistID: UUID!
checklistItem: TaskChecklistItem!
}
input UpdateTaskChecklistLocation {
checklistID: UUID!
taskChecklistID: UUID!
position: Float!
}
@ -541,19 +545,19 @@ type DeleteTaskChecklistPayload {
extend type Mutation {
createTaskGroup(input: NewTaskGroup!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateTaskGroupLocation(input: NewTaskGroupLocation!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
updateTaskGroupName(input: UpdateTaskGroupName!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTaskGroup(input: DeleteTaskGroupInput!):
DeleteTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DeleteTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
duplicateTaskGroup(input: DuplicateTaskGroup!):
DuplicateTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DuplicateTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
sortTaskGroup(input: SortTaskGroup!):
SortTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
SortTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTaskGroupTasks(input: DeleteTaskGroupTasks!):
DeleteTaskGroupTasksPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DeleteTaskGroupTasksPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
}
input DeleteTaskGroupTasks {
@ -612,19 +616,31 @@ type DeleteTaskGroupPayload {
}
input NewTaskGroup {
projectID: String!
projectID: UUID!
name: String!
position: Float!
}
extend type Mutation {
addTaskLabel(input: AddTaskLabelInput):
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
removeTaskLabel(input: RemoveTaskLabelInput):
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
toggleTaskLabel(input: ToggleTaskLabelInput!):
ToggleTaskLabelPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
}
input AddTaskLabelInput {
taskID: UUID!
projectLabelID: UUID!
}
input RemoveTaskLabelInput {
taskID: UUID!
taskLabelID: UUID!
}
input ToggleTaskLabelInput {
taskID: UUID!
projectLabelID: UUID!
@ -634,15 +650,6 @@ type ToggleTaskLabelPayload {
active: Boolean!
task: Task!
}
extend type Mutation {
addTaskLabel(input: AddTaskLabelInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
removeTaskLabel(input: RemoveTaskLabelInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
toggleTaskLabel(input: ToggleTaskLabelInput!):
ToggleTaskLabelPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
}
extend type Mutation {
deleteTeam(input: DeleteTeam!):
@ -758,7 +765,7 @@ type UpdateUserRolePayload {
}
input NewRefreshToken {
userId: String!
userID: UUID!
}
input NewUserAccount {
@ -771,7 +778,7 @@ input NewUserAccount {
}
input LogoutUser {
userID: String!
userID: UUID!
}
input DeleteUserAccount {

View File

@ -179,14 +179,9 @@ func (r *mutationResolver) UpdateProjectMemberRole(ctx context.Context, input Up
}
func (r *mutationResolver) CreateTask(ctx context.Context, input NewTask) (*db.Task, error) {
taskGroupID, err := uuid.Parse(input.TaskGroupID)
if err != nil {
log.WithError(err).Error("issue while parsing task group ID")
return &db.Task{}, err
}
createdAt := time.Now().UTC()
log.WithFields(log.Fields{"positon": input.Position, "taskGroupID": taskGroupID}).Info("creating task")
task, err := r.Repository.CreateTask(ctx, db.CreateTaskParams{taskGroupID, createdAt, input.Name, input.Position})
log.WithFields(log.Fields{"positon": input.Position, "taskGroupID": input.TaskGroupID}).Info("creating task")
task, err := r.Repository.CreateTask(ctx, db.CreateTaskParams{input.TaskGroupID, createdAt, input.Name, input.Position})
if err != nil {
log.WithError(err).Error("issue while creating task")
return &db.Task{}, err
@ -195,19 +190,14 @@ func (r *mutationResolver) CreateTask(ctx context.Context, input NewTask) (*db.T
}
func (r *mutationResolver) DeleteTask(ctx context.Context, input DeleteTaskInput) (*DeleteTaskPayload, error) {
taskID, err := uuid.Parse(input.TaskID)
if err != nil {
return &DeleteTaskPayload{}, err
}
log.WithFields(log.Fields{
"taskID": taskID.String(),
"taskID": input.TaskID,
}).Info("deleting task")
err = r.Repository.DeleteTaskByID(ctx, taskID)
err := r.Repository.DeleteTaskByID(ctx, input.TaskID)
if err != nil {
return &DeleteTaskPayload{}, err
}
return &DeleteTaskPayload{taskID.String()}, nil
return &DeleteTaskPayload{input.TaskID}, nil
}
func (r *mutationResolver) UpdateTaskDescription(ctx context.Context, input UpdateTaskDescriptionInput) (*db.Task, error) {
@ -226,11 +216,7 @@ func (r *mutationResolver) UpdateTaskLocation(ctx context.Context, input NewTask
}
func (r *mutationResolver) UpdateTaskName(ctx context.Context, input UpdateTaskName) (*db.Task, error) {
taskID, err := uuid.Parse(input.TaskID)
if err != nil {
return &db.Task{}, err
}
task, err := r.Repository.UpdateTaskName(ctx, db.UpdateTaskNameParams{taskID, input.Name})
task, err := r.Repository.UpdateTaskName(ctx, db.UpdateTaskNameParams{input.TaskID, input.Name})
return &task, err
}
@ -336,6 +322,16 @@ func (r *mutationResolver) CreateTaskChecklistItem(ctx context.Context, input Cr
return &taskChecklistItem, nil
}
func (r *mutationResolver) UpdateTaskChecklistLocation(ctx context.Context, input UpdateTaskChecklistLocation) (*UpdateTaskChecklistLocationPayload, error) {
checklist, err := r.Repository.UpdateTaskChecklistPosition(ctx, db.UpdateTaskChecklistPositionParams{Position: input.Position, TaskChecklistID: input.TaskChecklistID})
if err != nil {
return &UpdateTaskChecklistLocationPayload{}, err
}
return &UpdateTaskChecklistLocationPayload{Checklist: &checklist}, nil
}
func (r *mutationResolver) UpdateTaskChecklistItemName(ctx context.Context, input UpdateTaskChecklistItemName) (*db.TaskChecklistItem, error) {
task, err := r.Repository.UpdateTaskChecklistItemName(ctx, db.UpdateTaskChecklistItemNameParams{TaskChecklistItemID: input.TaskChecklistItemID,
Name: input.Name,
@ -375,34 +371,20 @@ func (r *mutationResolver) DeleteTaskChecklistItem(ctx context.Context, input De
}, err
}
func (r *mutationResolver) UpdateTaskChecklistLocation(ctx context.Context, input UpdateTaskChecklistLocation) (*UpdateTaskChecklistLocationPayload, error) {
checklist, err := r.Repository.UpdateTaskChecklistPosition(ctx, db.UpdateTaskChecklistPositionParams{Position: input.Position, TaskChecklistID: input.ChecklistID})
if err != nil {
return &UpdateTaskChecklistLocationPayload{}, err
}
return &UpdateTaskChecklistLocationPayload{Checklist: &checklist}, nil
}
func (r *mutationResolver) UpdateTaskChecklistItemLocation(ctx context.Context, input UpdateTaskChecklistItemLocation) (*UpdateTaskChecklistItemLocationPayload, error) {
currentChecklistItem, err := r.Repository.GetTaskChecklistItemByID(ctx, input.ChecklistItemID)
currentChecklistItem, err := r.Repository.GetTaskChecklistItemByID(ctx, input.TaskChecklistItemID)
checklistItem, err := r.Repository.UpdateTaskChecklistItemLocation(ctx, db.UpdateTaskChecklistItemLocationParams{TaskChecklistID: input.ChecklistID, TaskChecklistItemID: input.ChecklistItemID, Position: input.Position})
checklistItem, err := r.Repository.UpdateTaskChecklistItemLocation(ctx, db.UpdateTaskChecklistItemLocationParams{TaskChecklistID: input.TaskChecklistID, TaskChecklistItemID: input.TaskChecklistItemID, Position: input.Position})
if err != nil {
return &UpdateTaskChecklistItemLocationPayload{}, err
}
return &UpdateTaskChecklistItemLocationPayload{PrevChecklistID: currentChecklistItem.TaskChecklistID, ChecklistID: input.ChecklistID, ChecklistItem: &checklistItem}, err
return &UpdateTaskChecklistItemLocationPayload{PrevChecklistID: currentChecklistItem.TaskChecklistID, TaskChecklistID: input.TaskChecklistID, ChecklistItem: &checklistItem}, err
}
func (r *mutationResolver) CreateTaskGroup(ctx context.Context, input NewTaskGroup) (*db.TaskGroup, error) {
createdAt := time.Now().UTC()
projectID, err := uuid.Parse(input.ProjectID)
if err != nil {
return &db.TaskGroup{}, err
}
project, err := r.Repository.CreateTaskGroup(ctx,
db.CreateTaskGroupParams{projectID, createdAt, input.Name, input.Position})
db.CreateTaskGroupParams{input.ProjectID, createdAt, input.Name, input.Position})
return &project, err
}
@ -773,12 +755,7 @@ func (r *mutationResolver) DeleteUserAccount(ctx context.Context, input DeleteUs
}
func (r *mutationResolver) LogoutUser(ctx context.Context, input LogoutUser) (bool, error) {
userID, err := uuid.Parse(input.UserID)
if err != nil {
return false, err
}
err = r.Repository.DeleteRefreshTokenByUserID(ctx, userID)
err := r.Repository.DeleteRefreshTokenByUserID(ctx, input.UserID)
return true, err
}
@ -978,11 +955,7 @@ func (r *queryResolver) Users(ctx context.Context) ([]db.UserAccount, error) {
}
func (r *queryResolver) FindUser(ctx context.Context, input FindUser) (*db.UserAccount, error) {
userID, err := uuid.Parse(input.UserID)
if err != nil {
return &db.UserAccount{}, err
}
account, err := r.Repository.GetUserAccountByID(ctx, userID)
account, err := r.Repository.GetUserAccountByID(ctx, input.UserID)
if err == sql.ErrNoRows {
return &db.UserAccount{}, &gqlerror.Error{
Message: "User not found",

View File

@ -14,6 +14,9 @@ enum ObjectType {
TEAM
PROJECT
TASK
TASK_GROUP
TASK_CHECKLIST
TASK_CHECKLIST_ITEM
}
directive @hasRole(roles: [RoleLevel!]!, level: ActionLevel!, type: ObjectType!) on FIELD_DEFINITION
@ -55,7 +58,7 @@ input ProjectsFilter {
}
input FindUser {
userId: String!
userID: UUID!
}
input FindProject {

View File

@ -1,14 +1,14 @@
extend type Mutation {
createProjectLabel(input: NewProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
deleteProjectLabel(input: DeleteProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabel(input: UpdateProjectLabel!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabelName(input: UpdateProjectLabelName!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateProjectLabelColor(input: UpdateProjectLabelColor!):
ProjectLabel! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
ProjectLabel! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
}
input NewProjectLabel {

View File

@ -1,28 +1,28 @@
extend type Mutation {
createTask(input: NewTask!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTask(input: DeleteTaskInput!):
DeleteTaskPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DeleteTaskPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskDescription(input: UpdateTaskDescriptionInput!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskLocation(input: NewTaskLocation!):
UpdateTaskLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
UpdateTaskLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskName(input: UpdateTaskName!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
setTaskComplete(input: SetTaskComplete!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
updateTaskDueDate(input: UpdateTaskDueDate!):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
assignTask(input: AssignTaskInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
unassignTask(input: UnassignTaskInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: TASK)
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
}
input NewTask {
taskGroupID: String!
taskGroupID: UUID!
name: String!
position: Float!
}
@ -64,14 +64,14 @@ input NewTaskLocation {
}
input DeleteTaskInput {
taskID: String!
taskID: UUID!
}
type DeleteTaskPayload {
taskID: String!
taskID: UUID!
}
input UpdateTaskName {
taskID: String!
taskID: UUID!
name: String!
}

View File

@ -1,39 +1,40 @@
extend type Mutation {
createTaskChecklist(input: CreateTaskChecklist!):
TaskChecklist! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskChecklist! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
deleteTaskChecklist(input: DeleteTaskChecklist!):
DeleteTaskChecklistPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DeleteTaskChecklistPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistName(input: UpdateTaskChecklistName!):
TaskChecklist! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskChecklist! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
createTaskChecklistItem(input: CreateTaskChecklistItem!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!):
TaskChecklistItem! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!):
DeleteTaskChecklistItemPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistLocation(input: UpdateTaskChecklistLocation!):
UpdateTaskChecklistLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
UpdateTaskChecklistLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST)
updateTaskChecklistItemName(input: UpdateTaskChecklistItemName!):
TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
setTaskChecklistItemComplete(input: SetTaskChecklistItemComplete!):
TaskChecklistItem! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
deleteTaskChecklistItem(input: DeleteTaskChecklistItem!):
DeleteTaskChecklistItemPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
updateTaskChecklistItemLocation(input: UpdateTaskChecklistItemLocation!):
UpdateTaskChecklistItemLocationPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
UpdateTaskChecklistItemLocationPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_CHECKLIST_ITEM)
}
input UpdateTaskChecklistItemLocation {
checklistID: UUID!
checklistItemID: UUID!
taskChecklistID: UUID!
taskChecklistItemID: UUID!
position: Float!
}
type UpdateTaskChecklistItemLocationPayload {
checklistID: UUID!
taskChecklistID: UUID!
prevChecklistID: UUID!
checklistItem: TaskChecklistItem!
}
input UpdateTaskChecklistLocation {
checklistID: UUID!
taskChecklistID: UUID!
position: Float!
}

View File

@ -1,18 +1,18 @@
extend type Mutation {
createTaskGroup(input: NewTaskGroup!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: PROJECT)
updateTaskGroupLocation(input: NewTaskGroupLocation!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
updateTaskGroupName(input: UpdateTaskGroupName!):
TaskGroup! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
TaskGroup! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTaskGroup(input: DeleteTaskGroupInput!):
DeleteTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DeleteTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
duplicateTaskGroup(input: DuplicateTaskGroup!):
DuplicateTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DuplicateTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
sortTaskGroup(input: SortTaskGroup!):
SortTaskGroupPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
SortTaskGroupPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
deleteTaskGroupTasks(input: DeleteTaskGroupTasks!):
DeleteTaskGroupTasksPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
DeleteTaskGroupTasksPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK_GROUP)
}
input DeleteTaskGroupTasks {
@ -71,7 +71,7 @@ type DeleteTaskGroupPayload {
}
input NewTaskGroup {
projectID: String!
projectID: UUID!
name: String!
position: Float!
}

View File

@ -1,11 +1,23 @@
extend type Mutation {
addTaskLabel(input: AddTaskLabelInput):
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
removeTaskLabel(input: RemoveTaskLabelInput):
Task! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
toggleTaskLabel(input: ToggleTaskLabelInput!):
ToggleTaskLabelPayload! @hasRole(roles: [ADMIN, MEMBER], level: PROJECT, type: TASK)
}
input AddTaskLabelInput {
taskID: UUID!
projectLabelID: UUID!
}
input RemoveTaskLabelInput {
taskID: UUID!
taskLabelID: UUID!
}
input ToggleTaskLabelInput {
taskID: UUID!
projectLabelID: UUID!
@ -15,12 +27,3 @@ type ToggleTaskLabelPayload {
active: Boolean!
task: Task!
}
extend type Mutation {
addTaskLabel(input: AddTaskLabelInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
removeTaskLabel(input: RemoveTaskLabelInput):
Task! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
toggleTaskLabel(input: ToggleTaskLabelInput!):
ToggleTaskLabelPayload! @hasRole(roles: [ADMIN], level: PROJECT, type: PROJECT)
}

View File

@ -46,7 +46,7 @@ type UpdateUserRolePayload {
}
input NewRefreshToken {
userId: String!
userID: UUID!
}
input NewUserAccount {
@ -59,7 +59,7 @@ input NewUserAccount {
}
input LogoutUser {
userID: String!
userID: UUID!
}
input DeleteUserAccount {

View File

@ -1,2 +1,14 @@
#!/bin/bash
yarn --cwd frontend eslint $(echo $1 | sed 's/frontend\///g')
#!/bin/sh
PASS=true
for FILE in "$@"
do
yarn --cwd frontend run eslint $(echo $FILE | sed 's/frontend\///g')
if [ "$?" -eq 1 ]; then
PASS=false
fi
done
if [ "$PASS" = "false" ]; then
exit 1
fi