Accounts-passwordless - starting server-side code

This commit is contained in:
Renan Castro
2021-08-30 16:54:12 -03:00
committed by filipenevola
parent a16b6ba7bb
commit a1ae614535
3 changed files with 90 additions and 0 deletions

View File

@@ -23,4 +23,5 @@ Package.onUse(api => {
api.addFiles('email_templates.js', 'server');
api.addFiles('passwordless_server.js', 'server');
api.addFiles('passwordless_client.js', 'client');
api.addFiles('server_utils.js', 'server');
});

View File

@@ -0,0 +1,54 @@
import { Accounts } from 'meteor/accounts-base';
import {
handleError,
tokenValidator,
userQueryValidator,
} from './server_utils';
Accounts._checkToken = ({ user, token }) => {
const result = {
userId: user._id,
};
const userStoredToken = user.services.passwordless.token;
const { createdAt, sequence } = userStoredToken;
if(new Date(createdAt.getTime() + (Accounts._options.loginTokenExpirationHours*60*60*1000)) >= new Date()){
result.error = handleError("Expired token", false);
}
if(sequence !== token){
result.error = handleError("Sequence not found", false);
}
return result;
};
const checkToken = Accounts._checkToken;
// Handler to login with an ott.
Accounts.registerLoginHandler('passwordless', options => {
if (!options.token) return undefined; // don't handle
check(options, {
user: userQueryValidator,
token: tokenValidator(),
});
const user = Accounts._findUserByQuery(options.user, {
fields: {
services: 1,
},
});
if (!user) {
handleError('User not found');
}
if (
!user.services ||
!user.services.passwordless ||
!user.services.passwordless.token
) {
handleError('User has no token set');
}
return checkToken({ ...options, user });
});

View File

@@ -0,0 +1,35 @@
import {Accounts} from "meteor/accounts-base";
export const handleError = (msg, throwError = true) => {
const error = new Meteor.Error(
403,
Accounts._options.ambiguousErrorMessages
? "Something went wrong. Please check your credentials."
: msg
);
if (throwError) {
throw error;
}
return error;
};
export const NonEmptyString = Match.Where(x => {
check(x, String);
return x.length > 0;
});
export const userQueryValidator = Match.Where(user => {
check(user, {
id: Match.Optional(NonEmptyString),
username: Match.Optional(NonEmptyString),
email: Match.Optional(NonEmptyString),
});
if (Object.keys(user).length !== 1)
throw new Match.Error('User property must have exactly one field');
return true;
});
export const tokenValidator = () => {
const tokenLength = Accounts._options.tokenLength || 6;
return Match.Where(
str => Match.test(str, String) && str.length <= tokenLength
);
};