mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
Accounts-passwordless - starting server-side code
This commit is contained in:
committed by
filipenevola
parent
a16b6ba7bb
commit
a1ae614535
@@ -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');
|
||||
});
|
||||
|
||||
@@ -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 });
|
||||
});
|
||||
|
||||
35
packages/accounts-passwordless/server_utils.js
Normal file
35
packages/accounts-passwordless/server_utils.js
Normal 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
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user