import * as uuid from 'node-uuid'; import { GraphQLBoolean, GraphQLNonNull } from 'graphql'; import { authorized } from '../../auth'; import { createUser, updateUser, loginUser, updateUserPwd, linkUserUserToPaymentSystem, unlinkUserFromPaymentSystem, linkUserCard, addUserCard, removeUserCard, updateUserCardStatus, setDefaultUserCard, setUserPaymentMethod, deleteUser, } from '../userRepository'; import { IUser, IUserSelector, IUserUpdatePwd, ILinkCardData, IUserCardSelector, IUserPaymenMethod, IUserLoginMobile, } from '../../model/user'; import config from '../../config'; import { userType, createUserInputType, updateUserInputType, updateUserPwdInputType, userSelectorInputType, linkedCardType, linkCardInputType, userCardInputType, userPaymentMethodInputType, loggedUserType, loginUserInputType, uploadUserPicType, uploadUserPicInputType, } from './types'; import { publish } from '../../pubsub'; import { USER_CREATED, USER_UPDATED, } from './events'; const { FUNC_APP_URL, SAVE_BASE64_IMAGE_FUNC_CODE, USER_PIC_STORAGE_URL } = config; interface InputUser { input: IUser; } interface IInputUserLoginMobile { input: IUserLoginMobile; } interface InputUserPaymentMethod { input: IUserPaymenMethod; } interface InputUserCardSelector { input: IUserCardSelector; } interface InputLinkCard { input: ILinkCardData; } interface IUserSelectorInput { input: IUserSelector; } interface InputUpdateUserPwd { input: IUserUpdatePwd; } interface InputUploadUserPic { input: { image: string, fileName: string; }; } export default { createUser: { description: 'Creates new user', type: userType, args: { input: { type: new GraphQLNonNull(createUserInputType) }, }, resolve: authorized( ['AM', 'HR'], async (_: any, inputUser: InputUser) => { const input = inputUser.input; const user:Partial = await createUser(input); publish(USER_CREATED, user); return user; }, ), }, updateUser: { description: 'Updates user', type: userType, args: { input: { type: new GraphQLNonNull(updateUserInputType) }, }, resolve: authorized( ['AM', 'HR'], async (_: any, inputUser: InputUser, context: any) => { const input = inputUser.input; const user: Partial = await updateUser(input); publish(USER_UPDATED, user); return user; }, ), }, updateUserPwd: { description: 'Updates password', type: userType, args: { input: { type: new GraphQLNonNull(updateUserPwdInputType) }, }, resolve: authorized( ['AM', 'HR'], (_: any, inputUser: InputUpdateUserPwd, context: any) => { const input = inputUser.input; return updateUserPwd(input); }, ), }, linkUserToPaymentSystem: { description: 'Link executor to payment system', type: userType, args: { input: { type: new GraphQLNonNull(userSelectorInputType) }, }, resolve: authorized( ['AM', 'HR'], (_: any, inputUserSelector: IUserSelectorInput, context: any) => { const input = inputUserSelector.input; return linkUserUserToPaymentSystem(input.id); }, ), }, deleteUser: { description: 'Deletes user', type: GraphQLBoolean, args: { input: { type: new GraphQLNonNull(userSelectorInputType) }, }, resolve: authorized( ['AM'], (_: any, inputUserSelector: IUserSelectorInput, context: any) => { const input = inputUserSelector.input; return deleteUser(input.id); }, ), }, unlinkUserFromPaymentSystem: { description: 'Unlink executor from payment system', type: userType, args: { input: { type: new GraphQLNonNull(userSelectorInputType) }, }, resolve: authorized( ['AM', 'HR'], (_: any, inputUserSelector: IUserSelectorInput, context: any) => { const input = inputUserSelector.input; return unlinkUserFromPaymentSystem(input.id); }, ), }, linkUserCard: { description: 'Links payment system card id with temporary internal card id', type: linkedCardType, args: { input: { type: new GraphQLNonNull(linkCardInputType) }, }, resolve: authorized( ['HR', 'AM'], (_: any, inputLinkCard: InputLinkCard) => { const input = inputLinkCard.input; return linkUserCard(input); }), }, removeUserCard: { description: 'Adds payment system card id to user payment Info', type: userType, args: { input: { type: new GraphQLNonNull(userCardInputType) }, }, resolve: authorized( ['HR', 'AM'], (_: any, selector: InputUserCardSelector) => { const input = selector.input; return removeUserCard(input); }), }, updateUserCardStatus: { description: 'Synchronize status from payment system and internal system', type: userType, args: { input: { type: new GraphQLNonNull(userCardInputType) }, }, resolve: authorized( ['HR', 'AM'], (_: any, selector: InputUserCardSelector) => { const input = selector.input; return updateUserCardStatus(input); }), }, setDefaultUserCard: { description: 'Set default user card', type: userType, args: { input: { type: new GraphQLNonNull(userCardInputType) }, }, resolve: authorized( ['HR', 'AM'], (_: any, selector: InputUserCardSelector) => { const input = selector.input; return setDefaultUserCard(input); }), }, setUserPaymentMethod: { description: 'Set user payment method', type: userType, args: { input: { type: new GraphQLNonNull(userPaymentMethodInputType) }, }, resolve: authorized( ['HR', 'AM'], (_: any, input: InputUserPaymentMethod) => { return setUserPaymentMethod(input.input); }), }, addUserCard: { description: 'Links payment system card id with temporary internal card id', type: userType, args: { input: { type: new GraphQLNonNull(userCardInputType) }, }, resolve: authorized( ['HR', 'AM'], (_: any, selector: InputUserCardSelector) => { const input = selector.input; return addUserCard(input); }), }, loginUser: { description: 'Authorization endpoint', type: loggedUserType, args: { input: { type: new GraphQLNonNull(loginUserInputType) }, }, resolve: (_: any, inputUser: IInputUserLoginMobile) => { const input = inputUser.input; return loginUser(input); }, }, uploadUserPic: { description: 'Upload users picture', type: uploadUserPicType, args: { input: { type: new GraphQLNonNull(uploadUserPicInputType) }, }, resolve: authorized( ['AM', 'HR'], async (_: any, inputUserPic: InputUploadUserPic): Promise => { const { image } = inputUserPic.input; const fileName = `${inputUserPic.input.fileName}_${uuid.v4()}`; const body = JSON.stringify({ data: image, }); const thumbnailFuncUrl = `${FUNC_APP_URL}/api/img/user/${fileName}_thumbnail/small?code=${SAVE_BASE64_IMAGE_FUNC_CODE}`; // tslint:disable-line const thumbnailUrl = `${USER_PIC_STORAGE_URL}/${fileName}_thumbnail.jpg`; const originalFuncUrl = `${FUNC_APP_URL}/api/img/user/${fileName}/original?code=${SAVE_BASE64_IMAGE_FUNC_CODE}`; // tslint:disable-line await Promise.all([ fetch(thumbnailFuncUrl, { body, method: 'POST', }), fetch(originalFuncUrl, { body, method: 'POST', }), ]); return { thumbnailUrl }; }, ), }, };