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