Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
const emails = user.emails || [];
if (
!includes(
emails.map((email: EmailRecord) => email.address),
resetTokenRecord.address
)
) {
throw new Error(this.options.errors.resetPasswordLinkUnknownAddress);
}
const password = await this.hashAndBcryptPassword(newPassword);
// Change the user password and remove the old token
await this.db.setResetPassword(user.id, resetTokenRecord.address, password, token);
this.server.getHooks().emit(ServerHooks.ResetPasswordSuccess, user);
// If user clicked on an enrollment link we can verify his email
if (resetTokenRecord.reason === 'enroll') {
await this.db.verifyEmail(user.id, resetTokenRecord.address);
}
// Changing the password should invalidate existing sessions
if (this.options.invalidateAllSessionsAfterPasswordReset) {
await this.db.invalidateAllSessions(user.id);
}
if (this.options.notifyUserAfterPasswordChanged) {
const address = user.emails && user.emails[0].address;
if (!address) {
throw new Error(this.options.errors.noEmailSet);
}
}
return user;
},
});
const accountsServer = new AccountsServer(
{
db: new MongoDBInterface(db),
tokenSecret: 'secret',
},
{
password: accountsPassword,
}
);
accountsServer.on(ServerHooks.ValidateLogin, ({ user }) => {
// This hook is called every time a user try to login.
// You can use it to only allow users with verified email to login.
// If you throw an error here it will be returned to the client.
});
app.use(accountsExpress(accountsServer));
app.get('/user', userLoader(accountsServer), (req, res) => {
res.json({ user: (req as any).user });
});
app.listen(4000, () => {
console.log('Server listening on port 4000');
});
export const createAccounts = async () => {
const connection = await connect(process.env.DATABASE_URL);
// Like, fix this man!
const tokenSecret = 'process.env.ACCOUNTS_SECRET' || 'change this in .env';
const db = new AccountsTypeorm({ connection, cache: 1000 });
const password = new AccountsPassword();
const accountsServer = new AccountsServer(
{
db,
tokenSecret,
siteUrl: 'http://localhost:3000',
},
{ password }
);
// Creates resolvers, type definitions, and schema directives used by accounts-js
const accountsGraphQL = AccountsModule.forRoot({
accountsServer,
});
const typeDefs = `
type PrivateType @auth {
field: String
}
async function main() {
const mongoClient = await MongoClient.connect(MONGO_URI, {
useNewUrlParser: true,
native_parser: true
});
const db = mongoClient.db();
// Create accounts server that holds a lower level of all accounts operations
const accountsServer = new AccountsServer(
{
db: new AccountsMongoDB(db),
tokenSecret: TOKEN_SECRET
},
{
password: new AccountsPassword(),
}
);
const { schema, context } = AppModule.forRoot({
accountsServer,
db
});
const apolloServer = new ApolloServer({
schema,
context,
introspection: true
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
const accountsPassword = new AccountsPassword({
// This option is called when a new user create an account
// Inside we can apply our logic to validate the user fields
validateNewUser: user => {
// For example we can allow only some kind of emails
if (user.email.endsWith('.xyz')) {
throw new Error('Invalid email');
}
return user;
},
});
const accountsServer = new AccountsServer(
{
db: new MongoDBInterface(db),
tokenSecret: 'secret',
},
{
password: accountsPassword,
}
);
accountsServer.on(ServerHooks.ValidateLogin, ({ user }) => {
// This hook is called every time a user try to login.
// You can use it to only allow users with verified email to login.
// If you throw an error here it will be returned to the client.
});
app.use(accountsExpress(accountsServer));
});
const accountsPassword = new AccountsPassword({
// This option is called when a new user create an account
// Inside we can apply our logic to validate the user fields
validateNewUser: user => {
// For example we can allow only some kind of emails
if (user.email.endsWith('.xyz')) {
throw new Error('Invalid email');
}
return user;
},
});
// Create accounts server that holds a lower level of all accounts operations
const accountsServer = new AccountsServer(
{ db: accountsDb, tokenSecret: 'secret' },
{
password: accountsPassword,
}
);
// Creates resolvers, type definitions, and schema directives used by accounts-js
const accountsGraphQL = AccountsModule.forRoot({
accountsServer,
});
const typeDefs = gql`
type PrivateType @auth {
field: String
}
if (this.server.options.ambiguousErrorMessages) {
return;
}
throw new Error(this.options.errors.userNotFound);
}
// Do not send an email if the address is already verified
const emailRecord = find(
user.emails,
(email: EmailRecord) => email.address.toLowerCase() === address.toLocaleLowerCase()
);
if (!emailRecord || emailRecord.verified) {
return;
}
const token = generateRandomToken();
await this.db.addEmailVerificationToken(user.id, address, token);
const resetPasswordMail = this.server.prepareMail(
address,
token,
this.server.sanitizeUser(user),
'verify-email',
this.server.options.emailTemplates.verifyEmail,
this.server.options.emailTemplates.from
);
await this.server.options.sendMail(resetPasswordMail);
}
public async sendResetPasswordEmail(address: string): Promise {
if (!address || !isString(address)) {
throw new Error(this.options.errors.invalidEmail);
}
const user = await this.db.findUserByEmail(address);
if (!user) {
// To prevent user enumeration we fail silently
if (this.server.options.ambiguousErrorMessages) {
return;
}
throw new Error(this.options.errors.userNotFound);
}
const token = generateRandomToken();
await this.db.addResetPasswordToken(user.id, address, token, 'reset');
const resetPasswordMail = this.server.prepareMail(
address,
token,
this.server.sanitizeUser(user),
'reset-password',
this.server.options.emailTemplates.resetPassword,
this.server.options.emailTemplates.from
);
await this.server.options.sendMail(resetPasswordMail);
}
constructor() {
this.databaseTest = new DatabaseTest();
this.accountsDatabase = this.databaseTest.accountsDatabase;
this.accountsPassword = new AccountsPassword();
this.accountsServer = new AccountsServer(
{
db: this.accountsDatabase,
tokenSecret: 'test',
emailTemplates: {
from: 'accounts-js ',
verifyEmail: {
subject: () => 'Verify your account email',
text: (user: User, url: string) => convertUrlToToken(url),
},
resetPassword: {
subject: () => 'Reset your password',
text: (user: User, url: string) => convertUrlToToken(url),
},
enrollAccount: {
subject: () => 'Set your password',
text: (user: User, url: string) => convertUrlToToken(url),
constructor() {
this.databaseTest = new DatabaseTest();
this.accountsDatabase = this.databaseTest.accountsDatabase;
this.accountsPassword = new AccountsPassword();
this.accountsServer = new AccountsServer(
{
db: this.accountsDatabase,
tokenSecret: 'test',
emailTemplates: {
from: 'accounts-js ',
verifyEmail: {
subject: () => 'Verify your account email',
text: (user: User, url: string) => convertUrlToToken(url),
},
resetPassword: {
subject: () => 'Reset your password',
text: (user: User, url: string) => convertUrlToToken(url),
},
enrollAccount: {
subject: () => 'Set your password',
text: (user: User, url: string) => convertUrlToToken(url),