diff --git a/backend/src/apis/loginAPI.ts b/backend/src/apis/loginAPI.ts index 1aa6cace1..7160db68c 100644 --- a/backend/src/apis/loginAPI.ts +++ b/backend/src/apis/loginAPI.ts @@ -11,10 +11,10 @@ export const apiPost = async (url: string, payload: unknown): Promise => { if (result.data.state !== 'success') { throw new Error(result.data.msg) } - return { success: true, result } + return { success: true, data: result.data } }) .catch((error) => { - return { success: false, result: error } + return { success: false, data: error.message } }) } @@ -29,11 +29,11 @@ export const apiGet = async (url: string): Promise => { if (!['success', 'warning'].includes(result.data.state)) { throw new Error(result.data.msg) } - return { success: true, result: result } + return { success: true, data: result.data } }) .catch((error) => { // eslint-disable-next-line no-console console.log('IN apiGet.ERROR: ' + JSON.stringify({ success: false, result: error })) - return { success: false, result: error } + return { success: false, data: error.message } }) } diff --git a/backend/src/graphql/inputs/TransactionInput.ts b/backend/src/graphql/inputs/TransactionInput.ts index 279e09dd6..db010390a 100644 --- a/backend/src/graphql/inputs/TransactionInput.ts +++ b/backend/src/graphql/inputs/TransactionInput.ts @@ -1,5 +1,4 @@ -import { ObjectType, ArgsType, Field, Int, Float } from 'type-graphql' -import { Entity, BaseEntity, Column, Double } from 'typeorm' +import { ArgsType, Field } from 'type-graphql' @ArgsType() export class TransactionInput { diff --git a/backend/src/graphql/models/Balance.ts b/backend/src/graphql/models/Balance.ts index 2ba34ec75..ceb479b9c 100644 --- a/backend/src/graphql/models/Balance.ts +++ b/backend/src/graphql/models/Balance.ts @@ -1,10 +1,11 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { Entity, BaseEntity, Column } from 'typeorm' import { ObjectType, Field } from 'type-graphql' @Entity() @ObjectType() export class Balance extends BaseEntity { - // eslint-disable-next-line @typescript-eslint/no-explicit-any constructor(json: any) { super() this.balance = json.balance diff --git a/backend/src/graphql/models/BaseResponse.ts b/backend/src/graphql/models/BaseResponse.ts new file mode 100644 index 000000000..712660bd3 --- /dev/null +++ b/backend/src/graphql/models/BaseResponse.ts @@ -0,0 +1,9 @@ +import { Entity, BaseEntity } from 'typeorm' +import { ObjectType, Field } from 'type-graphql' + +@Entity() +@ObjectType() +export class BaseResponse extends BaseEntity { + @Field(() => Boolean) + success: boolean +} diff --git a/backend/src/graphql/models/ChangePasswordResponse.ts b/backend/src/graphql/models/ChangePasswordResponse.ts new file mode 100644 index 000000000..1ba3247cd --- /dev/null +++ b/backend/src/graphql/models/ChangePasswordResponse.ts @@ -0,0 +1,9 @@ +import { Entity, BaseEntity } from 'typeorm' +import { ObjectType, Field } from 'type-graphql' + +@Entity() +@ObjectType() +export class ChangePasswordResponse extends BaseEntity { + @Field(() => String) + state: string +} diff --git a/backend/src/graphql/models/CheckUsernameResponse.ts b/backend/src/graphql/models/CheckUsernameResponse.ts new file mode 100644 index 000000000..ac51b64e1 --- /dev/null +++ b/backend/src/graphql/models/CheckUsernameResponse.ts @@ -0,0 +1,15 @@ +import { Entity, BaseEntity } from 'typeorm' +import { ObjectType, Field } from 'type-graphql' + +@Entity() +@ObjectType() +export class CheckUsernameResponse extends BaseEntity { + @Field(() => String) + state: string + + @Field(() => String) + msg?: string + + @Field(() => Number) + groupId?: number +} diff --git a/backend/src/graphql/models/CreateResponse.ts b/backend/src/graphql/models/CreateResponse.ts new file mode 100644 index 000000000..54276b031 --- /dev/null +++ b/backend/src/graphql/models/CreateResponse.ts @@ -0,0 +1,14 @@ +import { Entity, BaseEntity } from 'typeorm' +import { ObjectType, Field } from 'type-graphql' + +@Entity() +@ObjectType() +export class CreateResponse extends BaseEntity { + constructor(json: any) { + super() + this.state = json.state + } + + @Field(() => String) + state: string +} diff --git a/backend/src/graphql/models/LoginResponse.ts b/backend/src/graphql/models/LoginResponse.ts new file mode 100644 index 000000000..2abe1ef96 --- /dev/null +++ b/backend/src/graphql/models/LoginResponse.ts @@ -0,0 +1,25 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +import { Entity, BaseEntity, Column } from 'typeorm' +import { ObjectType, Field } from 'type-graphql' +import { User } from './User' + +// temporaray solution until we have JWT implemented + +@Entity() +@ObjectType() +export class LoginResponse extends BaseEntity { + constructor(json: any) { + super() + this.sessionId = json.session_id + this.user = new User(json.user) + } + + @Field(() => Number) + @Column() + sessionId: number + + @Field(() => User) + @Column() + user: User +} diff --git a/backend/src/graphql/models/LoginViaVerificationCode.ts b/backend/src/graphql/models/LoginViaVerificationCode.ts new file mode 100644 index 000000000..bd0d66781 --- /dev/null +++ b/backend/src/graphql/models/LoginViaVerificationCode.ts @@ -0,0 +1,22 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ +import { Entity, BaseEntity, Column } from 'typeorm' +import { ObjectType, Field } from 'type-graphql' + +@Entity() +@ObjectType() +export class LoginViaVerificationCode extends BaseEntity { + constructor(json: any) { + super() + this.sessionId = json.session_id + this.email = json.user.email + } + + @Field(() => Number) + @Column() + sessionId: number + + @Field(() => String) + @Column() + email: string +} diff --git a/backend/src/graphql/models/SendEmailResponse.ts b/backend/src/graphql/models/SendEmailResponse.ts new file mode 100644 index 000000000..d8e163478 --- /dev/null +++ b/backend/src/graphql/models/SendEmailResponse.ts @@ -0,0 +1,18 @@ +import { Entity, BaseEntity } from 'typeorm' +import { ObjectType, Field } from 'type-graphql' + +@Entity() +@ObjectType() +export class SendEmailResponse extends BaseEntity { + constructor(json: any) { + super() + this.state = json.state + this.msg = json.msg + } + + @Field(() => String) + state: string + + @Field(() => String) + msg?: string +} diff --git a/backend/src/graphql/models/Server.ts b/backend/src/graphql/models/Server.ts new file mode 100644 index 000000000..e722a2c97 --- /dev/null +++ b/backend/src/graphql/models/Server.ts @@ -0,0 +1,14 @@ +import { Entity, BaseEntity } from 'typeorm' +import { ObjectType, Field } from 'type-graphql' + +@Entity() +@ObjectType() +export class Server extends BaseEntity { + constructor(json: any) { + super() + this.loginServerPath = json.login_server_path + } + + @Field(() => String) + loginServerPath: string +} diff --git a/backend/src/graphql/models/UpdateUserInfosResponse.ts b/backend/src/graphql/models/UpdateUserInfosResponse.ts new file mode 100644 index 000000000..14f834932 --- /dev/null +++ b/backend/src/graphql/models/UpdateUserInfosResponse.ts @@ -0,0 +1,15 @@ +import { Entity, BaseEntity } from 'typeorm' +import { ObjectType, Field } from 'type-graphql' + +@Entity() +@ObjectType() +export class UpdateUserInfosResponse extends BaseEntity { + @Field(() => String) + state: string + + @Field(() => Number) + validValues: number + + @Field(() => [String]) + errors: [string] +} diff --git a/backend/src/graphql/models/User.ts b/backend/src/graphql/models/User.ts index b935871d1..68543bf09 100644 --- a/backend/src/graphql/models/User.ts +++ b/backend/src/graphql/models/User.ts @@ -1,3 +1,5 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +/* eslint-disable @typescript-eslint/explicit-module-boundary-types */ import { Entity, BaseEntity, Column } from 'typeorm' import { ObjectType, Field } from 'type-graphql' @@ -9,6 +11,15 @@ export class User extends BaseEntity { @PrimaryGeneratedColumn() id: number */ + constructor(json: any) { + super() + this.email = json.email + this.firstName = json.first_name + this.lastName = json.last_name + this.username = json.username + this.description = json.description + this.language = json.language + } @Field(() => String) @Column({ length: 191 }) @@ -70,115 +81,3 @@ export class User extends BaseEntity { publisherId: number */ } - -// temporaray solution until we have JWT implemented -@Entity() -@ObjectType() -export class LoginResponse extends BaseEntity { - @Field(() => Number) - @Column() - sessionId: number - - @Field(() => User) - @Column() - user: User -} - -@Entity() -@ObjectType() -export class LoginViaVerificationCode extends BaseEntity { - @Field(() => Number) - @Column() - sessionId: number - - @Field(() => String) - @Column() - email: string -} - -@Entity() -@ObjectType() -export class LogoutResponse extends BaseEntity { - @Field(() => String) - state: string -} - -@Entity() -@ObjectType() -export class CreateResponse extends BaseEntity { - @Field(() => String) - state: string -} - -@Entity() -@ObjectType() -export class SendEmailResponse extends BaseEntity { - @Field(() => String) - state: string - - @Field(() => String) - msg?: string -} - -@Entity() -@ObjectType() -export class Server extends BaseEntity { - @Field(() => String) - loginServerPath: string -} - -@Entity() -@ObjectType() -export class ErrorData extends BaseEntity { - @Field(() => String) - messages: string -} - -@Entity() -@ObjectType() -export class GetUserInfoResponse extends BaseEntity { - @Field(() => String) - state: string - - @Field(() => User) - userData: User - - @Field(() => Server) - server: Server - - @Field(() => [ErrorData]) - errors: [ErrorData] -} - -@Entity() -@ObjectType() -export class ChangePasswordResponse extends BaseEntity { - @Field(() => String) - state: string -} - -@Entity() -@ObjectType() -export class UpdateUserInfosResponse extends BaseEntity { - @Field(() => String) - state: string - - @Field(() => Number) - validValues: number - - @Field(() => [ErrorData]) - errors: [ErrorData] -} - -@Entity() -@ObjectType() -export class CheckUsernameResponse extends BaseEntity { - @Field(() => String) - state: string - - @Field(() => String) - msg?: string - - @Field(() => Number) - groupId?: number -} diff --git a/backend/src/graphql/models/UserInfoData.ts b/backend/src/graphql/models/UserInfoData.ts new file mode 100644 index 000000000..46b336d5e --- /dev/null +++ b/backend/src/graphql/models/UserInfoData.ts @@ -0,0 +1,38 @@ +import { Entity, BaseEntity } from 'typeorm' +import { ObjectType, Field } from 'type-graphql' +import { Server } from './Server' +import { User } from './User' + +@Entity() +@ObjectType() +export class UserInfoData extends BaseEntity { + constructor(json: any) { + super() + this.state = json.state + this.userData = new User(json.user_data) + this.server = new Server(json.server) + this.errors = json.errors + } + + @Field(() => String) + state: string + + @Field(() => User) + userData: User + + @Field(() => Server) + server: Server + + @Field(() => [String]) + errors: [string] +} + +@Entity() +@ObjectType() +export class GetUserInfoResponse extends BaseEntity { + @Field(() => Boolean) + success: boolean + + @Field(() => UserInfoData) + data: UserInfoData +} diff --git a/backend/src/graphql/resolvers/CommunityTransactionResolver.ts b/backend/src/graphql/resolvers/CommunityTransactionResolver.ts index 7eb7a9921..1fcc214e7 100644 --- a/backend/src/graphql/resolvers/CommunityTransactionResolver.ts +++ b/backend/src/graphql/resolvers/CommunityTransactionResolver.ts @@ -41,7 +41,7 @@ export class CommunityTransactionResolver { } @Query(() => String) - async create( + async createCoins( @Args() { sessionId, email, amount, memo, targetDate = new Date() }: TransactionCreateArgs, ): Promise { const payload = { diff --git a/backend/src/graphql/resolvers/UserResolver.ts b/backend/src/graphql/resolvers/UserResolver.ts index 723f7539e..d22dd49ac 100644 --- a/backend/src/graphql/resolvers/UserResolver.ts +++ b/backend/src/graphql/resolvers/UserResolver.ts @@ -1,17 +1,14 @@ // import jwt from 'jsonwebtoken' import { Resolver, Query, /* Mutation, */ Args, Arg } from 'type-graphql' import CONFIG from '../../config' -import { - ChangePasswordResponse, - CheckUsernameResponse, - CreateResponse, - GetUserInfoResponse, - LoginResponse, - LoginViaVerificationCode, - LogoutResponse, - SendEmailResponse, - UpdateUserInfosResponse, -} from '../models/User' +import { ChangePasswordResponse } from '../models/ChangePasswordResponse' +import { CheckUsernameResponse } from '../models/CheckUsernameResponse' +import { CreateResponse } from '../models/CreateResponse' +import { GetUserInfoResponse } from '../models/UserInfoData' +import { LoginResponse } from '../models/LoginResponse' +import { LoginViaVerificationCode } from '../models/LoginViaVerificationCode' +import { SendEmailResponse } from '../models/SendEmailResponse' +import { UpdateUserInfosResponse } from '../models/UpdateUserInfosResponse' import { ChangePasswordArgs, CheckUsernameArgs, @@ -27,27 +24,17 @@ import { apiPost, apiGet } from '../../apis/loginAPI' export class UserResolver { @Query(() => LoginResponse) // eslint-disable-next-line @typescript-eslint/no-explicit-any - async login(@Args() { email, password }: UnsecureLoginArgs): Promise { + async login(@Args() { email, password }: UnsecureLoginArgs): Promise { email = email.trim().toLowerCase() const result = await apiPost(CONFIG.LOGIN_API_URL + 'unsecureLogin', { email, password }) // if there is no user, throw an authentication error if (!result.success) { - throw new Error(result.result) + throw new Error(result.data) } // temporary solution until we have JWT implemented - return { - sessionId: result.result.data.session_id, - user: { - email: result.result.data.user.email, - language: result.result.data.user.language, - username: result.result.data.user.username, - firstName: result.result.data.user.first_name, - lastName: result.result.data.user.last_name, - description: result.result.data.user.description, - }, - } + return new LoginResponse(result.data) // create and return the json web token // The expire doesn't help us here. The client needs to track when the token expires on its own, @@ -65,29 +52,35 @@ export class UserResolver { @Query(() => LoginViaVerificationCode) // eslint-disable-next-line @typescript-eslint/no-explicit-any - async loginViaEmailVerificationCode(@Arg('optin') optin: string): Promise { + async loginViaEmailVerificationCode( + @Arg('optin') optin: string, + ): Promise { // I cannot use number as type here. // The value received is not the same as sent by the query const result = await apiGet( CONFIG.LOGIN_API_URL + 'loginViaEmailVerificationCode?emailVerificationCode=' + optin, ) - if (result.success) - return { - sessionId: result.result.data.session_id, - email: result.result.data.user.email, - } - return result.result + if (!result.success) { + throw new Error(result.data) + } + return new LoginViaVerificationCode(result.data) } - @Query(() => LogoutResponse) - async logout(@Arg('sessionId') sessionId: number): Promise { + /* @Query(() => LogoutResponse) + // eslint-disable-next-line @typescript-eslint/no-explicit-any + async logout(@Arg('sessionId') sessionId: number): Promise { const payload = { session_id: sessionId } - const result = apiPost(CONFIG.LOGIN_API_URL + 'logout', payload); - return result + const result = apiPost(CONFIG.LOGIN_API_URL + 'logout', payload) + if (!result.success) { + throw new Error(result.data) + } + return result.data } - +*/ @Query(() => CreateResponse) - async create(@Args() { email, firstName, lastName, password }: CreateUserArgs): Promise { + async create( + @Args() { email, firstName, lastName, password }: CreateUserArgs, + ): Promise { const payload = { email, first_name: firstName, @@ -96,7 +89,11 @@ export class UserResolver { emailType: 2, login_after_register: true, } - return apiPost(CONFIG.LOGIN_API_URL + 'createUser', payload) + const result = await apiPost(CONFIG.LOGIN_API_URL + 'createUser', payload) + if (!result.success) { + throw new Error(result.data) + } + return new CreateResponse(result.data) } @Query(() => SendEmailResponse) diff --git a/backend/src/graphql/resolvers/helpers/MapVariableToColumnName.ts b/backend/src/graphql/resolvers/helpers/MapVariableToColumnName.ts new file mode 100644 index 000000000..e69de29bb