Return URL on verification - meteor

What sets the return URL for the verification email. Not the link that gets generated and inserted in the email, but when you click the link, it ends up going to a page on your site after its verified. How can I set what page it goes to?

You can set the URL by specifying Accounts.emailTemplates.verifyEmail.text. Here's an example:
Accounts.emailTemplates.siteName = 'MyApp';
Accounts.emailTemplates.from = 'me#example.com';
Accounts.emailTemplates.verifyEmail.subject = function() {
return 'Verify your email address on MyApp';
};
Accounts.emailTemplates.verifyEmail.text = function(user, url) {
var token = url.split('/').pop();
var verifyEmailUrl = Meteor.absoluteUrl("verify-email/" + token);
return verifyEmailEmailBody(verifyEmailUrl);
};
The callback takes a url parameter which is the default URL generated by meteor. You can extract the verification token and then use it to build a custom URL. The function needs to return a body string, which you'll generate by implementing verifyEmailEmailBody.
On the client, you'll need to set up the corresponding route. When the route is run, you can call Accounts.verifyEmail.

You can change the verification url used in the email and then handle that route yourself. Here I'll use /verify and redirect to /wherever if successful.
client
var match = window.location.pathname.match(/^\/verify\/(.*)$/);
var token;
if (match) {
token = match[1];
}
Meteor.startup(function () {
if (token) {
Accounts.verifyEmail(token, function (error) {
if (!error) {
window.location.pathname = '/wherever';
}
});
}
});
server
Accounts.urls.verifyEmail = function (token) {
return Meteor.absoluteUrl('verify/' + token);
};

Related

How to cutomise the url sent with Meteor Accounts.ui forgetpassword

I'm using accounts.ui for forget password
Accounts.forgotPassword({email: "test#test.com"}, function (e, r) {
if (e) {
console.log(e.reason);
} else {
// success
}
});
When I send the email for forget password I simply get below email
Can someone tell me how to simply change the url and send the token with the same token
I tried using below code but that didn't work
main.js(client)
Meteor.startup(() => {
Accounts.resetPassword.text = function(user, url) {
url = url.replace('#/', '/');
console.log("url ==== ", url)
return `Click this link to reset your password: ${url}`;
}
});
On the server side:
Accounts.emailTemplates.resetPassword.subject = function () {
return "Forgot your password?";
};
Accounts.emailTemplates.resetPassword.text = function (user, url) {
return "Click this link to reset your password:\n\n" + url;
};
Read: https://docs.meteor.com/api/passwords.html#Accounts-emailTemplates
To change the resetPassword url to a custom one you have to run below code on your server (inside of /server/main.js file).
Accounts.urls.resetPassword = function (token) {
return FlowRouter.url("/reset-password/:token/", { token });
};
In this case, I am using a FlowRouter to generate that URL but you could technically just return a template literal if you like.
If the above code is in the server main.js file and you run Accounts.forgotPassword() function on the frontend from a localhost, it would generate this link:
http://localhost:3000/reset-password/C9cGfgaLEgGXbCVYJcCLnDYiRi3XJpmt2irLOOaKe56

Meteor registration verification email not sent on production

I have tested my meteor app on dev and the verification email is sent out. But on production it is not. Could it maybe the content of smtp.js? My code is as follows:
// server/smtp.js
Meteor.startup(function () {
var smtp = {
username: 'dummy#wbs.co.za',
password: 'hw783378hjshd',
server: 'smtp.wbs.co.za',
port: 25
}
process.env.MAIL_URL = 'smtp://' + encodeURIComponent(smtp.username) + ':' + encodeURIComponent(smtp.password)
+ '#' + encodeURIComponent(smtp.server) + ':' + smtp.port;
});
// (server-side)
Meteor.startup(function() {
// By default, the email is sent from no-reply#meteor.com. If you wish to receive email from users asking for help with their account, be sure to set this to an email address that you can receive email at.
Accounts.emailTemplates.from = 'NOREPLY <no-reply#meteor.com>';
// The public name of your application. Defaults to the DNS name of the application (eg: awesome.meteor.com).
Accounts.emailTemplates.siteName = 'No Reply';
// A Function that takes a user object and returns a String for the subject line of the email.
Accounts.emailTemplates.verifyEmail.subject = function(user) {
return 'Confirm Your Email Address';
};
// A Function that takes a user object and a url, and returns the body text for the email.
// Note: if you need to return HTML instead, use Accounts.emailTemplates.verifyEmail.html
Accounts.emailTemplates.verifyEmail.html = function(user, url) {
return 'click on the following link to verify your email address: ' + url;
};
});
// (server-side) called whenever a login is attempted
Accounts.validateLoginAttempt(function(attempt){
if (attempt.user && attempt.user.emails && !attempt.user.emails[0].verified ) {
console.log('email not verified');
throw new Meteor.Error(403, 'Verification email has been sent to your email address. Use the url in the email to verify yourself.');
return false; // the login is aborted
}
return true;
});
Please help.

Custom Meteor enroll template

In my application I want to seed the database with users and send them an enrollment link to activate their account (and choose a password). I also want them to verify/change some profile data.
On the server I seed the database like this:
Meteor.startup(function () {
if(Meteor.users.find().count() === 0) {
var user_id = Accounts.createUser({ email: 'some#email.com', profile: { some: 'profile' } });
Accounts.sendEnrollmentEmail(user_id);
}
})
The enrollment link is sent as expected, but I want to create a custom template for when the url in the email is clicked. Preferably handled by iron-router. (Not using the accounts-ui package).
I tried things like redirecting the user to a custom route like this:
var doneCallback, token;
Accounts.onEnrollmentLink(function (token, done) {
doneCallback = done;
token = token;
Router.go('MemberEnroll')
});
which is not working (it changes the url but not rendering my template)
I also tried to change the enroll URL on the server like this:
Accounts.urls.enrollAccount = function (token) {
return Meteor.absoluteUrl('members/enroll/' + token);
};
But when I do this, the Accounts.onEnrollmentLink callback does not fire.
Also, changing the URL is not documented so I'm not sure its a good practice at all.
Any help is appreciated.
In my application I'm doing like this
this.route('enroll', {
path: '/enroll-account/:token',
template: 'enroll_page',
onBeforeAction: function() {
Meteor.logout();
Session.set('_resetPasswordToken', this.params.token);
this.subscribe('enrolledUser', this.params.token).wait();
},
data: function() {
if(this.ready()){
return {
enrolledUser: Meteor.users.findOne()
}
}
}
})
As enrollment url is like this
http://www.yoursite.com/enroll-account/hkhk32434kh42hjkhk43
when users click on the link they will redirect to this template and you can render your template
In my publication
Meteor.publish('enrolledUser', function(token) {
return Meteor.users.find({"services.password.reset.token": token});
});
After taking the password from the user
Accounts.resetPassword(token, creds.password,function(e,r){
if(e){
alert("Sorry we could not reset your password. Please try again.");
}else{
alert("Logged In");
Router.go('/');
}
})
enroll link
Accounts.urls.enrollAccount = function (token) {
return Meteor.absoluteUrl('enroll-account/' + token);
};
Im afraid now isnt possible, what i did is changing the html and css using "rendered" function but it has some probs with delay
Meteor.startup(function(){
Template["_enrollAccountDialog"].rendered = function(){
document.getElementById('enroll-account-password-label').innerHTML = 'Escolha sua senha';
$('.accounts-dialog').css('background-color','#f4f5f5');
$('.accounts-dialog').css('text-align','center');
$('.accounts-dialog').removeAttr('width');
document.getElementById('login-buttons-enroll-account-button').className = ' create-account-button';
document.getElementById('login-buttons-enroll-account-button').innerHTML = 'Criar conta';
}
});

Impacts on refreshing access tokens frequently

On my .NET Web API 2 server, I am using OWIN for authentication. I have followed Taiseer's tutorial and successfully implemented an access token refresh mechanism.
I would like to know if there are any impacts on anything if clients refresh their access tokens frequently, e.g. refresh once every 5 minutes on average.
I am asking this question because I have a button on my page, when user clicks it, the data on that page is sent to different endpoints. These endpoints are marked with the attribute [Authorize].
Previously, when I send a request to a single protected endpoint, I can check if the response is 401 (unauthorized). If so, I can refresh the user's access token first, then resend the rejected request with the new token. However, I don't know how can the same thing be done this time, as there are so many requests being sent at once. The aforementioned method is implemented in my AngularJS interceptor. It can handle a single but not multiple rejected unauthorized requests.
FYI, here is the code for my interceptor, which is found and modified from a source on GitHub.
app.factory('authInterceptor', function($q, $injector, $location, localStorageService) {
var authInterceptor = {};
var $http;
var request = function(config) {
config.headers = config.headers || {};
var jsonData = localStorageService.get('AuthorizationData');
if (jsonData) {
config.headers.Authorization = 'Bearer ' + jsonData.token;
}
return config;
}
var responseError = function(rejection) {
var deferred = $q.defer();
if (rejection.status === 401) {
var authService = $injector.get('authService');
authService.refreshToken().then(function(response) {
_retryHttpRequest(rejection.config, deferred);
}, function() {
authService.logout();
$location.path('/login');
deferred.reject(rejection);
});
} else {
deferred.reject(rejection);
}
return deferred.promise;
}
var _retryHttpRequest = function(config, deferred) {
$http = $http || $injector.get('$http');
$http(config).then(function(response) {
deferred.resolve(response);
}, function(response) {
deferred.reject(response);
});
}
authInterceptor.request = request;
authInterceptor.responseError = responseError;
return authInterceptor;
});

How to save an element in a collection with data fetched from a webservice api

A user saves a trip (from a city to another one) and before storing it into the mongo collection, my app have to fetch the trip distance and time from the mapquest api.
How and where would you put the HTTP.call ? Server side ? Client side ?
Install http module:
meteor add http
Create a server method to call web service. Here is my example where the user put URL and the code returns title of page.
Server code:
if (Meteor.isServer) {
Meteor.startup(function () {
// code to run on server at startup
Meteor.methods({
getTitle: function(url) {
var response = Meteor.http.call("GET", url);
return response;
}
});
And here is a client code:
Template.new_bookmark.events({
// add new bookmark
'keyup #add-bookmark' : function(e,t) {
if(e.which === 13)
{
var url = String(e.target.value || "");
if(url) {
Meteor.call("getTitle", url, function(err, response) {
var url_title = response.content.match(/<title[^>]*>([^<]+)<\/title>/)[1];
var timestamp = new Date().getTime();
bookmarks.insert({Name:url_title,URL:url,tags:["empty"], Timestamp: timestamp});
});
}
}
}
});
If the user press "enter" in the #add-bookmark field, I get fields value and pass it to server method. The sever method returns page HTML source and I parse it on client, get title and store it on my collection.

Resources