172 lines
7.9 KiB
TypeScript
172 lines
7.9 KiB
TypeScript
import { ApolloError } from 'apollo-server-lambda';
|
|
import { Resolver, Query, Ctx, Authorized, Mutation, Arg } from 'type-graphql';
|
|
|
|
import { ApolloContext } from '@seed/interfaces/context';
|
|
import { editOneGeneric } from '@seed/graphql/BaseService';
|
|
|
|
import { signinAnonymous, signinGeneric } from './services/AccountService';
|
|
|
|
import AccountModel, { EditAccountInput } from '@src/accounts/account.model';
|
|
import { AccountTypeEnum } from '@src/accounts/account.components';
|
|
import { FirebaseTokenResult, SimpleResult } from '@seed/interfaces/components';
|
|
import { ResetPasswordInput, NewEmailInput, NewPasswordInput, LoginInput, LinkEmailInput } from './account.components';
|
|
import Firebase from '@seed/services/auth/FirebaseService';
|
|
import { sendEmail } from '@seed/services/email/EmailService';
|
|
import { AvailableTranslation } from '@src/__components/components';
|
|
import FirebaseAuth from '@seed/services/auth/FirebaseAuthService';
|
|
import { newError } from '@seed/helpers/Error';
|
|
|
|
@Resolver(AccountModel)
|
|
export default class AccountBaseResolver {
|
|
/*
|
|
███████╗██╗███████╗██╗ ██████╗ ███████╗
|
|
██╔════╝██║██╔════╝██║ ██╔══██╗██╔════╝
|
|
█████╗ ██║█████╗ ██║ ██║ ██║███████╗
|
|
██╔══╝ ██║██╔══╝ ██║ ██║ ██║╚════██║
|
|
██║ ██║███████╗███████╗██████╔╝███████║
|
|
╚═╝ ╚═╝╚══════╝╚══════╝╚═════╝ ╚══════╝
|
|
*/
|
|
|
|
/*
|
|
██████╗ ██╗ ██╗███████╗██████╗ ██╗ ██╗
|
|
██╔═══██╗██║ ██║██╔════╝██╔══██╗╚██╗ ██╔╝
|
|
██║ ██║██║ ██║█████╗ ██████╔╝ ╚████╔╝
|
|
██║▄▄ ██║██║ ██║██╔══╝ ██╔══██╗ ╚██╔╝
|
|
╚██████╔╝╚██████╔╝███████╗██║ ██║ ██║
|
|
╚══▀▀═╝ ╚═════╝ ╚══════╝╚═╝ ╚═╝ ╚═╝
|
|
*/
|
|
@Query(() => AccountModel)
|
|
@Authorized()
|
|
async me(@Ctx() ctx: ApolloContext): Promise<AccountModel> {
|
|
return ctx.ctx.user as AccountModel;
|
|
}
|
|
|
|
/*
|
|
* Auth side
|
|
*/
|
|
@Query(() => FirebaseTokenResult)
|
|
async login(
|
|
@Ctx() ctx: ApolloContext,
|
|
@Arg('creds', { nullable: true }) creds?: LoginInput,
|
|
@Arg('refreshToken', { nullable: true }) refreshToken?: string,
|
|
): Promise<FirebaseTokenResult> {
|
|
if (creds) {
|
|
const account = new AccountModel();
|
|
await account.getOne({ email: creds.email }, null);
|
|
|
|
return FirebaseAuth.getInstance().loginWithEmailPassword(creds);
|
|
}
|
|
if (refreshToken) return FirebaseAuth.getInstance().loginWithRefreshToken(refreshToken);
|
|
|
|
return signinAnonymous(ctx);
|
|
}
|
|
|
|
@Query(() => SimpleResult)
|
|
async magicLink(@Arg('input') input: ResetPasswordInput, @Ctx() ctx: ApolloContext): Promise<SimpleResult> {
|
|
const account = new AccountModel();
|
|
|
|
try {
|
|
await account.getOne({ email: input.email }, null);
|
|
const magicLink = await Firebase.getInstance().getMagicLink(input.email);
|
|
|
|
await sendEmail('magicLink', account.language, account.email, { ...account, magicLink });
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
|
|
return { message: 'sent' };
|
|
}
|
|
|
|
/*
|
|
███╗ ███╗██╗ ██╗████████╗ █████╗ ████████╗ ██████╗ ██████╗ ███████╗
|
|
████╗ ████║██║ ██║╚══██╔══╝██╔══██╗╚══██╔══╝██╔═══██╗██╔══██╗██╔════╝
|
|
██╔████╔██║██║ ██║ ██║ ███████║ ██║ ██║ ██║██████╔╝███████╗
|
|
██║╚██╔╝██║██║ ██║ ██║ ██╔══██║ ██║ ██║ ██║██╔══██╗╚════██║
|
|
██║ ╚═╝ ██║╚██████╔╝ ██║ ██║ ██║ ██║ ╚██████╔╝██║ ██║███████║
|
|
╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝ ╚═╝ ╚═╝╚══════╝
|
|
*/
|
|
|
|
/*
|
|
* Account side
|
|
*/
|
|
|
|
// @Mutation(() => AccountModel)
|
|
// async register(@Arg('input') input: NewAccountInput, @Ctx() ctx: ApolloContext): Promise<AccountModel> {
|
|
// const model = new AccountModel();
|
|
// return signinGeneric(model, AccountTypeEnum.user, input, ctx);
|
|
// }
|
|
|
|
@Mutation(() => AccountModel)
|
|
@Authorized()
|
|
async updateMe(@Arg('input') input: EditAccountInput, @Ctx() ctx: ApolloContext): Promise<AccountModel> {
|
|
const model = new AccountModel();
|
|
return editOneGeneric(model, ctx.ctx.user._id, input, ctx);
|
|
}
|
|
|
|
@Mutation(() => AccountModel)
|
|
@Authorized()
|
|
async updateMeEmail(@Arg('input') input: NewEmailInput, @Ctx() ctx: ApolloContext): Promise<AccountModel> {
|
|
const currentUser = ctx.ctx.user as AccountModel;
|
|
try {
|
|
await Firebase.getInstance().updateEmail({ uid: currentUser._id, email: input.newEmail });
|
|
return editOneGeneric(currentUser, currentUser._id, { email: input.newEmail }, ctx);
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
@Mutation(() => AccountModel)
|
|
@Authorized()
|
|
async updateMePassword(@Arg('input') input: NewPasswordInput, @Ctx() ctx: ApolloContext): Promise<AccountModel> {
|
|
const currentUser = ctx.ctx.user as AccountModel;
|
|
|
|
if (input.newPassword != input.newPasswordConfirmation) throw newError(2006);
|
|
|
|
try {
|
|
// Check old password
|
|
FirebaseAuth.getInstance().loginWithEmailPassword({
|
|
email: currentUser.email,
|
|
password: input.oldPassword,
|
|
});
|
|
} catch (error) {
|
|
throw newError(20060);
|
|
}
|
|
|
|
try {
|
|
await Firebase.getInstance().updatePassword({ uid: currentUser._id, password: input.newPassword });
|
|
return currentUser;
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
@Mutation(() => SimpleResult)
|
|
async resetPassword(@Arg('input') input: ResetPasswordInput, @Ctx() ctx: ApolloContext): Promise<SimpleResult> {
|
|
const account = new AccountModel();
|
|
|
|
try {
|
|
await account.getOne({ email: input.email }, null);
|
|
const resetPasswordLink = await Firebase.getInstance().getResetPasswordLink(input.email);
|
|
|
|
await sendEmail('resetPassword', account.language, account.email, { ...account, resetPasswordLink });
|
|
} catch (error) {
|
|
throw error;
|
|
}
|
|
|
|
return { message: 'sent' };
|
|
}
|
|
|
|
@Mutation(() => AccountModel)
|
|
@Authorized('public')
|
|
async registerGuest(
|
|
@Arg('input') input: LinkEmailInput,
|
|
@Arg('otherInfo') otherInfo: EditAccountInput,
|
|
@Ctx() ctx: ApolloContext,
|
|
): Promise<AccountModel> {
|
|
const account = new AccountModel();
|
|
|
|
const result = await FirebaseAuth.getInstance().linkWithEmailPassword(input);
|
|
return editOneGeneric(account, result.localId, { ...otherInfo, email: result.email, types: [AccountTypeEnum.user] }, ctx);
|
|
}
|
|
}
|