From 4a2ba8406dececec039aee05298a2571d88b0dfd Mon Sep 17 00:00:00 2001 From: Christoph Lienhard Date: Fri, 28 May 2021 23:27:37 +0200 Subject: [PATCH] #20 Return person on change role mutation Return the whole person object on calling the changeRole mutation. This enables the apollo cache in the frontend to automatically update the role of the given user. Furthermore, made all create function statements idempotent by deleting them first if existing. --- backend/sql/04_setup_authentication.sql | 34 ++++++++++++------- .../src/backend/mutations/userRole.ts | 31 ++++++++--------- redaktions-app/src/backend/queries/person.ts | 2 +- 3 files changed, 36 insertions(+), 31 deletions(-) diff --git a/backend/sql/04_setup_authentication.sql b/backend/sql/04_setup_authentication.sql index e6bb725..11cff79 100644 --- a/backend/sql/04_setup_authentication.sql +++ b/backend/sql/04_setup_authentication.sql @@ -1,6 +1,8 @@ create extension if not exists "pgcrypto"; + -- Define JWT claim structure +drop type if exists candymat_data.jwt_token cascade; create type candymat_data.jwt_token as ( role text, @@ -8,6 +10,9 @@ create type candymat_data.jwt_token as exp bigint ); + +-- Function to get the currently logged-in person +drop function if exists candymat_data.current_person; create function candymat_data.current_person( ) returns candymat_data.person as $$ @@ -17,6 +22,9 @@ where row_id = nullif(current_setting('jwt.claims.person_row_id', true), '')::in $$ language sql stable; grant execute on function candymat_data.current_person() to candymat_person; + +-- Function to register a new user +drop function candymat_data.register_person; create function candymat_data.register_person( first_name text, last_name text, @@ -47,9 +55,11 @@ begin end ; $$ language plpgsql strict security definer; - grant execute on function candymat_data.register_person(text, text, text, text) to candymat_anonymous; + +-- Authenticate: Login for user +drop function if exists candymat_data.authenticate; create function candymat_data.authenticate( email text, password text @@ -80,26 +90,24 @@ $$ language plpgsql strict security definer; grant execute on function candymat_data.authenticate(text, text) to candymat_anonymous, candymat_person; + +-- Change role: Changes role for a given user. Only editors are allowed to use it. +drop function if exists candymat_data.change_role; create function candymat_data.change_role( person_row_id integer, new_role candymat_data.role ) - returns table - ( - first_name text, - last_name text, - role candymat_data.role - ) -as + returns candymat_data.person as $$ +declare + person candymat_data.person; begin update candymat_data.person set role = new_role - where candymat_data.person.row_id = $1; + where candymat_data.person.row_id = $1 + returning * into person; - return query select candymat_data.person.first_name::text, candymat_data.person.last_name::text, new_role - from candymat_data.person - where person.row_id = person_row_id; + return person; end; -$$ language plpgsql; +$$ language plpgsql strict security definer; grant execute on function candymat_data.change_role(integer, candymat_data.role) to candymat_editor; diff --git a/redaktions-app/src/backend/mutations/userRole.ts b/redaktions-app/src/backend/mutations/userRole.ts index f9b2259..7836b60 100644 --- a/redaktions-app/src/backend/mutations/userRole.ts +++ b/redaktions-app/src/backend/mutations/userRole.ts @@ -1,29 +1,26 @@ import { gql } from "@apollo/client"; +import { UppercaseUserRole } from "../../jwt/jwt"; +import { BasicPersonFragment, BasicPersonResponse } from "../queries/person"; export const ChangeRole = gql` - mutation ChangeRole ( - $firstName: String! - $lastName: String! - $role: String! - ){ - __typename - changeRole(input: {newRole: CANDYMAT_EDITOR, personRowId: 3}) { - results { - firstName - lastName - role - } - } + mutation ChangeRole($personRowId: Int!, $newRole: Role!) { + changeRole(input: { personRowId: $personRowId, newRole: $newRole }) { + person { + ...BasicPersonFragment + } } + } + ${BasicPersonFragment} `; export interface ChangeRoleVariables { - email: string; - password: string; + personRowId: number; + newRole: UppercaseUserRole; } export interface ChangeRoleResponse { - authenticate: { - jwtToken?: string; + __typename: "Mutation"; + changeRole: { + person?: BasicPersonResponse; }; } diff --git a/redaktions-app/src/backend/queries/person.ts b/redaktions-app/src/backend/queries/person.ts index 689bcfc..c5d1de0 100644 --- a/redaktions-app/src/backend/queries/person.ts +++ b/redaktions-app/src/backend/queries/person.ts @@ -1,7 +1,7 @@ import { gql } from "@apollo/client"; import { UppercaseUserRole } from "../../jwt/jwt"; -const BasicPersonFragment = gql` +export const BasicPersonFragment = gql` fragment BasicPersonFragment on Person { id rowId