import { GraphQLError } from 'graphql'; import { ClaimVerifyResult } from './cognito-client'; export const RESOURCE = 'https://graphql.photowall.com'; export enum Scopes { ORDERS_READ = 'orders.read', ORDERS_WRITE = 'orders.write', DESIGNERS_READ = 'designers.read', DESIGNERS_PUBLIC_READ = 'designers.public.read', DESIGNERS_WRITE = 'designers.write', PRODUCTS_READ = 'products.read', PRODUCTS_PUBLIC_READ = 'products.public.read', PRODUCTS_WRITE = 'products.write', CATEGORIES_READ = 'categories.read', CATEGORIES_PUBLIC_READ = 'categories.public.read', CATEGORIES_WRITE = 'categories.write', MARKETS_READ = 'markets.read', KEYWORDS_READ = 'keywords.read', KEYWORDS_WRITE = 'keywords.write', LOCALES_READ = 'locales.read', TEXTS_READ = 'texts.read', INTERIORS_READ = 'interiors.read', INTERIORS_PUBLIC_READ = 'interiors.public.read', INTERIORS_WRITE = 'interiors.write', } function getScopes(user: ClaimVerifyResult): Scopes[] | [] { if (user.accessToken) { const authScopes = user.accessToken.scope.split(' '); return authScopes .map((scopeStr) => { if (scopeStr.indexOf(RESOURCE) === 0) { return Scopes[ scopeStr .replace(`${RESOURCE}/`, '') .replaceAll('.', '_') .toLocaleUpperCase() ]; } return null; }) .filter(Boolean); } return []; } function throwForbidden() { throw new GraphQLError('You are not authorized to perform this action', { extensions: { code: 'FORBIDDEN', http: { status: 403, }, }, }); } export const ScopeAccess = (() => { const validationObject = (scopes) => { return { scopes, all(input: Scopes[]) { if (input.length === 0) throwForbidden(); // GUARD // If the input list contains something thats not in this.scopes array // then when we concat the lists and remove duplicates the length will be larger // in the new list than this.scopes. const checkList = [...new Set(this.scopes.concat(input))]; if (checkList.length === this.scopes.length) return this; throwForbidden(); }, some(input: Scopes[]) { if (input.length === 0) throwForbidden(); // GUARD for (const s of input) { if (this.scopes.includes(s)) { return this; } } throwForbidden(); }, }; }; return { validate(user) { // If ifToken user then give full access. // TODO: Should this be removed? if (user.idToken) { if (user.idToken['custom:adgroups'].includes('WebAdmin')) { return validationObject(Object.values(Scopes)); } } // If development environment and Basic auth user // push all scopes to give full access if ( (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') && user.userName === 'development_basic_user' ) { return validationObject(Object.values(Scopes)); } // AccessToken with scopes return validationObject(getScopes(user)); }, }; })();