i am using meteor accounts for login and user registration.
When a user hits the bottom line (register):
He gets redirected to the create account page:
The code behind these pages is a mixture of jade templates and javascript.
template(name="userFormsLayout")
section.auth-layout
section.auth-dialog
+Template.dynamic(template=content)
It seems like the content is replaced when hitting the register link and this is as far as my knowledge goes...
I would like to prevent users from creating new accounts by either disabling the final register button on the registration page and / or disable the complete registration page.
I am also open for other solutions to prevent useers from registering.
RELATED:
How can I set forbidClientAccountCreation to false in Meteor?
UPDATE:
I also tried this
AccountsTemplates.configure({
forbidClientAccountCreation: true
but got:
Error: signUp route configured but forbidClientAccountCreation set to true!
Can anyone help me with this issue?
i don't have the whole answer, but i can give you a couple pieces to get you started.
first, you can tell AccountsTemplates (AT) to use your layout. you can put this anywhere that's loaded to both client and server, e.g. lib/atConfig:
AccountsTemplates.configureRoute('signIn', {
layoutTemplate: 'LoginLayout'
});
here's the layout template:
<template name="LoginLayout">
<main>
<div>
{{> Template.dynamic template=main}}
</div>
</main>
</template>
in the JS, you can hide the bits of the template you don't want the user to see. here, i'm hiding the password form and a separator. you can dig into the DOM to figure out which bits you want to hide:
Template.LoginLayout.onRendered(function() {
this.autorun(() => {
if (this.subscriptionsReady()) {
Tracker.afterFlush(() => {
$('.at-pwd-form').remove();
$('.at-sep').remove();
});
}
});
});
for the server, you can check for new user attempts and reject them if they're made w/ username and password. i think this should work, but you may have to play around with it:
import {Meteor} from 'meteor/meteor';
Meteor.startup(() => {
/**
* reject registration via username/password.
*/
Accounts.validateNewUser(function(attemptInfo) {
if (attemptInfo && attemptInfo.services && attemptInfo.services.password) {
return false;
}
return true;
});
});
Your last Error comes from sending conflicting message to Accounts setup. You might want to remove your route configuration for the signup page?
Related
I am coding an web application which has PayPal button, HTML form and HTML button. In my web application I am using HTML, CSS, JavaScript and Python Flask in the back-end.
Firstly the user of the web application is supposed to make a payment via PayPal. Secondly after the successful payment the HTML submit button appears and the user is allowed to submit the HTML form to make a database query. Thirdly the database query results are shown to the user and HTML button is supposed to disappear.
How should I make this HTML button appear and disappear correctly? I am trying to prevent that the users of my web application are not able to make my HTML button visible without paying? Are users for example able to make HTML button visible by injecting CSS or JavaScript?
I made my first version of the web application in the following way below: Firstly the HTML button is hidden (CSS) and secondly when the PayPal payment is made the JavaScript function makeButtonVisible() makes the HTML button visible. Thirdly the HTML button disappears when Python Flask renders the website again and shows the database query results.
CSS
#html-button {
visibility: hidden;
}
JAVASCRIPT
var CREATE_PAYMENT_URL = 'http://127.0.0.1:5000/payment';
var EXECUTE_PAYMENT_URL = 'http://127.0.0.1:5000/execute';
paypal.Button.render(
{
env: 'sandbox', // Or 'sandbox'
commit: true, // Show a 'Pay Now' button
payment: function () {
return paypal.request.post(CREATE_PAYMENT_URL).then(function (data) {
return data.paymentID;
});
},
onAuthorize: function (data) {
return paypal.request
.post(EXECUTE_PAYMENT_URL, { paymentID: data.paymentID, payerID: data.payerID })
.then(function (res) {
console.log(res.success);
makeButtonVisible();
// The payment is complete!
// You can now show a confirmation message to the customer
});
},
},
'#paypal-button',
);
function makeButtonVisible() {
document.getElementById('html-button').style.visibility = 'visible';
}
PYTHON FLASK
return render_template("index.html")
A secure design captures the payment on the server side and then allows the payer to proceed with whatever action.
You'll need two routes that return JSON, one for 'Create an Order' and one for 'Capture Order', documented here. There is a Checkout-Python-SDK you can use.
Pair your two routes with the following front-end UI for approval: https://developer.paypal.com/demo/checkout/#/pattern/server
Once capture is successful (and recorded as such in your server database before returning the success JSON to your client), there are various ways you can proceed with using JavaScript to "unhide" or display a form. Since the capture occurred on a server, you'll be able to use that fact to validate form submission against an actual payment record existing in your database, and reject it otherwise.
If possible you'll also want to update the URL so the user can refresh the page or come back to it later and still be able to submit a form for that payment.
Struggling to understand how to achieve this, even though it's extremely commonplace across the web.
I have two modals, one is a "sign up" modal, the other is a "log in" modal. I need to be able to perform both actions via a user's Google account. I am successfully creating and logging in users via the Google API.
The trouble comes with the fact that Google's drop-in button automatically signs the user in.
On the page I have:
<div class="g-signin2" data-onsuccess="googleSignUp"></div>
And later:
<div class="g-signin2" data-onsuccess="googleLogIn"></div>
Obviously these two buttons have different onsuccess functions, but both are being called when the user is logged in. I have somewhat alleviated the problem by only actually getting the Google script on a button click:
$('a#google-login').click(function() {
$.getScript('https://apis.google.com/js/platform.js');
})
But the behaviour of this whole setup is less than ideal. Is there a common fix for this? It seems incredibly frustrating that Google automatically runs onsuccess functions if the user is logged in (eg without any user action). What's the point of having a button if it runs without user action?
So: I want to be able to log users in via Google, and also sign users up via Google, but only if the user actually clicks a button, in both cases.
You can achieve what you want by implementing Google Sign-In buttons with imperative approach. My recommendation is to use the custom buttons. That way you will get more control over the API. Check out this doc:
https://developers.google.com/identity/sign-in/web/build-button
And this video might help as well.
https://www.youtube.com/watch?v=Oy5F9h5JqEU]
Here's a sample code
https://github.com/GoogleChrome/google-sign-in
As #agektmr said I used the custom button as described in here https://developers.google.com/identity/sign-in/web/build-button
After that you can create 2 buttons and used a different callback for each one.
This is the code that I had it working with within my react component so thats why I'm referencing auth2 from the window object, but you might not need that if your using vanilla JS, This also contains some ES6 so sorry if your not using ES6, you can just convert () => {} to function () { } and let to var
// This method is from the above cited article, I have just altered it slightly so
// that you can input a success callback as a parameter rather than hard coding just one
function attachElementToCallback(element, success) {
window.auth2.attachClickHandler(element, {}, success
, (error) => {
var message = JSON.stringify(error, undefined, 2);
alert(message)
});
}
function initializeGoogleStuff() {
window.gapi.load('auth2', () => {
window.auth2 = window.gapi.auth2.init({
prompt: "select_account",
})
let signInElement = window.document.getElementById("signInButton")
if (signInElement) {
attachElementToCallback(signInElement, handleLogin)
}
let signUpElement = window.document.getElementById("signUpButton")
if (signUpElement) {
attachElementToCallback(signUpElement, (response) => console.log(response))
}
})
}
for the html (this is just copied and pasted from the above article and duplicated, they have the CSS and further instructions if you want to make it comply with googles branding guidelines (which is a must if you want them to verify your app) https://developers.google.com/identity/branding-guidelines
<div id="signInButton" class="customGPlusSignIn">
<span class="icon"></span>
<span class="buttonText">Sign In</span>
</div>
<div id="signUpButton" class="customGPlusSignIn">
<span class="icon"></span>
<span class="buttonText">Sign Up</span>
</div>
If I type website.com/about-us/ in the address bar it breaks.
Says "Not Found" instead of loading the page
If I type website.com/#!/about-us in the address bar, it goes to the right page. // Added hashbang or #!
If I click a link on the page to website.com/about-us/ (without the hashbang), it works. How do I fix it so I can just go to the website without a hash bang from the address bar?
$locationProvider.html5Mode(true);
Update
Here's my server config
app.route('/').get(index.render); // UPDATE: This is why the home page was loading and I could click links
app.get('/.\*', function (req, res, next) {
if(req.url.substring(0,4) === "/api") {
return next();
} else {
res.send(index.render) // render is a function in the index controller
}
});
TL;DR: link clicks work as expected because your JavaScript has already loaded
Since your using a UI router, link clicks are "told" by Angular to go to the appropriate hashbang route unless you use $locationProvider.html5Mode(true);, which you are. So in this case, link clicks know to use html5Mode because the JavaScript in your page has already loaded.
When you enter the link in the address bar manually, the JavaScript hasn't had a chance to load, so it doesn't "know" to map the appropriate non-hashbang route to the correct view in your app.
To get the desired behavior, you'll need to configure your server to route correctly:
app.get('/some-page', doStuff);
I'm using the hot towel template, and I'm trying to understand how to navigate to a different view via a javascript call. When my page loads, it looks like this:
Then, if I click any other button, then click the apps button again, I wrote some test code to just take the user to the ping page. This is in the apps view model:
function activate() {
if (initialized) { router.navigateTo("#/ping"); return; }
// more code here (doesn't get hit the second time through)
}
But what happens is the URL is correctly the ping URL, and the ping button is selected, but the actual content is still showing the applications:
If I want to navigate to another page without clicking in the navbar at the top, how should that be done?
Your 'router.navigateTo('#/ping') is correct.
But when activate method is called, lots of heavy tasks are being done by durandal, it's too late for
your commanding, if you want to prevent opening a page and instead of that You'd like to go to
another page , then you can use 'CanActivate' method as following :
function canActivate() {
if (initialized) { router.navigateTo("#/ping"); return false;
/* return false to prevent opening a page */ }
else return true;
}
Also your application's performance will be boosted too
Good luck.
//Update:
With help I managed to catch some errors which fixed the token issue. I've updated the code to reflect that. The code still doesn't produce an event on the timeline though so I'm leaving the question up.
Original question:
I'm trying to build a simple script using the Open Graph API that will push a link to a visited page (containing a movie) to Facebook, once the visitor hits the page.
I'm not using a custom action and object, but the standard Watch action (https://developers.facebook.com/docs/opengraph/video/) and Video.movie object.
I came up with this based on FB's example code:
<!-- first login-button with scope publish_actions: -->
<fb:login-button show-faces="false" width="200" max-rows="1" scope="publish_actions" ></fb:login-button>
<!-- Then script that should push update to timeline: -->
<script type="text/javascript">
function fbPublish(){
FB.api(
'/me/video.watches',
'post',
{ 'video.movie': '<?php the_permalink(); ?>',
'access_token': 'blablabla' },
function(response) {
if (!response || response.error) {
alert('Nope.');
} else {
alert('Yes.'); // any stuff
}
});
}
This triggers the alert 'Nope'.
I have added the Watch action through curl.
Any ideas as to what could be going on?
You still need to FB.login before you can automatically post to the user's timeline.
FB.login(function(response) {
// Post the action
}, {scope: 'publish_actions'});
While I didn't check the validity of your actual code to post the action, you problem is that before you can do this, you'll need the user's permission. The publish_actions permission is the one you'll need but I think its already included in new Auth Dialogs. Just leave it there to be sure.
Do the FB.login code first, you'll get a popup "Allow" dialog, after that, is the time you can freely post in the user's wall. It's a part of the security, Facebook users wouldnt want you posting on their timeline without them knowing.