pubnub Access manager(PAM) grants revoke() is not working? - publish-subscribe

I've enabled PAM on my pubnub account. I have a simple chat application, where I revoked grants on a channel as follows:
pubnub.grant(
{
channels:[channel,channel+'-pnpres'],
ttl: 2, // 0 for infinite
read: false, // false to disallow
write: false, // false to disallow
manage: false,
},
function (status) {
// handle state setting response
console.log(" status = "+status);
});
});
But, I'm still able to continue chat on that channel. Expectation is since, I shouldn't be allowed to publish/subscribe to that channel as I removed read/write/manage grants.
Why is it not happening?

PubNub Access Manager and the Secret Key
The issue was resolved in PubNub Support. For current versions of PubNub SDKs (v4x and some of the last releases of 3x - check Feature Matrix and/or changlelogs to verify), when you init PubNub with the secret key, it has all access to any/all channels and channel groups without the need for an auth-key and you cannot revoke access on a client that has the secret-key.
Documentation is being updated about this this behavior to be more prominent.

Related

How to make user elegible for FB push campaign in phonegap app?

I am using this plugin:
https://www.npmjs.com/package/cordova-plugin-facebook-push-campaign
Also followed the instructions in this link. I have added this line:
cordova.plugins.FacebookPushCampaign.register(pushToken);
But it seems that this is not reflecting in my FB analytics. When I tried creating push campaign, and sent a push notification it results to 0 notifications delivered.I manually send a notif on my phone and it works. So maybe the plugin is not registering the token toFB correctly?
Have anyone tried this plugin before?
Okay, after a day of debugging. I followed again what is stated in the plugin's documentation and it seems working fine now. What happened is that I was confused about the comment in the documentation.
// grab the token and pass it to Facebook
cordova.plugins.FacebookPushCampaign.register(pushToken);
So what I did was (which is INCORRECT):
cordova.plugins.FacebookPushCampaign.register(pushToken.registrationId); //I passed the device token itself
But I realized that the FB analytics accepts the whole response of the registration event (CORRECT):
pushPlugin
.init({
ios: {
badge: 'true',
sound: 'true',
alert: 'true',
clearBadge: 'true',
}
})
// wait for the plugin to register the Push Token
.on('registration', function(pushToken) {
// grab the token and pass it to Facebook
//pushToken looks like {'registrationId':xxxxx}
cordova.plugins.FacebookPushCampaign.register(pushToken); //Yes, pass the response of the registration event
});
LESSON: Read the documentation. If the documentation is confusing, test it and see if you misunderstood something (like what happened to me).

SAP GATEWAY & UI5: How can reset the CSRF token?=

I need to reset the CSRF token in an OData model. Based on the UI5 documentation I am trying to do that with refreshSecurityToken(fnSuccess?, fnError?, bAsync?) function. (click here for reference)
I wrote the following code:
var oDataModel = this.getOwnerComponent().getModel("ZMDM_ODATA_FILE_SRV");
oDataModel.setTokenHandlingEnabled(true);
oDataModel.refreshSecurityToken(function() {
var token = oDataModel.getSecurityToken();
console.log(token);
// can upload the file if token reset
});
The problem is that this token is not reset for 30 minutes and that is our session timeout. Actually it is valid during the session lifetime. I even checked the following link:
https://blogs.sap.com/2014/08/26/gateway-protection-against-cross-site-request-forgery-attacks/
Actually many people had this problem, but I couldn't find a clear solution for resetting the token. I did all the required steps in the front-end for the sending a Head request for resting the token. I think something is missing regarding the back-end gateway settings or ABAP coding.
What do I have to do?
You can delete a CSRF Token (per user/token) via transaction SM05.
seems like you need to set a interval in your front-end application to fetch and update the token more often. But that's a paradox: if your back-end sets the timeout for 30 minutes, why would you keep it live for more time?
SecurityToken timeout is important to make sure the active session is being used and that no individual "forgot" it and left the system open and unwatched/unused.
But if you really need to keep your front-end session always available and force the back-end to be too, you can setInterval() to fetch the CSRF and update the application:
var oDataModel = this.getOwnerComponent().getModel("ZMDM_ODATA_FILE_SRV");
oDataModel.setTokenHandlingEnabled(true);
var fnRefreshToken = oDataModel.refreshSecurityToken(function() {
var token = oDataModel.getSecurityToken();
console.log(token);
// can upload the file if token reset
});
window.setInterval(function(){
fnRefreshToken;
}, 1800000); // where 1.800.000 miliseconds represents 30 minutes
And then you should store your new token in the token variable and allow upload if token is reset.
Kindly regards,
Henrique Mattos

Swift2 Firebase: Is the email check done on the backend server? [duplicate]

Question says it all. In Firebase, how do I confirm email when a user creates an account, or, for that matter, do password reset via email.
I could ask more broadly: is there any way to send emails out from Firebase? E.g. notifications, etc. This isn't the kind of thing you would usually do client-side.
Update
Note that this was never a very secure way of handling email verification, and since Firebase now supports email verification, it should probably be used instead.
Original answer
I solved the email verification using the password reset feature.
On account creation I give the user a temporary (randomly generated) password. I then trigger a password reset which will send an email to the user with a link. The link will allow the user to set a new password.
To generate a random password you can use code similar to this:
function () {
var possibleChars = ['abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!?_-'];
var password = '';
for(var i = 0; i < 16; i += 1) {
password += possibleChars[Math.floor(Math.random() * possibleChars.length)];
}
return password;
}
Note that this is happening on the client, so a malicious user could tamper with your logic.
This would need to be done outside of firebase. I store users at /users/ and keep a status on them (PENDING, ACTIVE, DELETED). I have a small service that monitors users of a PENDING status and sends out a confirmation email. Which has a link to a webservice I've created to update the user status to ACTIVE.
[Engineer at Firebase - Update 2014-01-27]
Firebase Simple Login now supports password resets for email / password authentication.
Each of the Simple Login client libraries has been given a new method for generating password reset emails for the specified email address - sendPasswordResetEmail() on the Web and Android, and sendPasswordResetForEmail() on iOS.
This e-mail will contain a temporary token that the user may use to log into their account and update their credentials. This token will expire after 24 hours or when the user changes their password, whichever occurs first.
Also note that Firebase Simple Login enables full configuration of the email template as well as the sending address (including whitelabel email from your domain for paid accounts).
To get access to this feature, you'll need to update your client library to a version of v1.2.0 or greater. To grab the latest version, check out https://www.firebase.com/docs/downloads.html.
Also, check out https://www.firebase.com/docs/security/simple-login-email-password.html for the latest Firebase Simple Login - Web Client docs.
As at 2016 July, you might not have to use the reset link etc. Just use the sendEmailVerification() and applyActionCode functions:
In short, below is basically how you'll approach this, in AngularJS:
// thecontroller.js
$scope.sendVerifyEmail = function() {
console.log('Email sent, whaaaaam!');
currentAuth.sendEmailVerification();
}
// where currentAuth came from something like this:
// routerconfig
....
templateUrl: 'bla.html',
resolve: {
currentAuth:['Auth', function(Auth) {
return Auth.$requireSignIn() // this throws an AUTH_REQUIRED broadcast
}]
}
...
// intercept the broadcast like so if you want:
....
$rootScope.$on("$stateChangeError", function(event, toState, toParams, fromState, fromParams, error) {
if (error === "AUTH_REQUIRED") {
$state.go('login', { toWhere: toState });
}
});
....
// So user receives the email. How do you process the `oobCode` that returns?
// You may do something like this:
// catch the url with its mode and oobCode
.state('emailVerify', {
url: '/verify-email?mode&oobCode',
templateUrl: 'auth/verify-email.html',
controller: 'emailVerifyController',
resolve: {
currentAuth:['Auth', function(Auth) {
return Auth.$requireSignIn()
}]
}
})
// Then digest like so where each term is what they sound like:
.controller('emailVerifyController', ['$scope', '$stateParams', 'currentAuth', 'DatabaseRef',
function($scope, $stateParams, currentAuth, DatabaseRef) {
console.log(currentAuth);
$scope.doVerify = function() {
firebase.auth()
.applyActionCode($stateParams.oobCode)
.then(function(data) {
// change emailVerified for logged in User
console.log('Verification happened');
})
.catch(function(error) {
$scope.error = error.message;
console.log(error.message, error.reason)
})
};
}
])
And ooh, with the above approach, I do not think there's any need keeping the verification of your user's email in your user data area. The applyActionCode changes the emailVerified to true from false.
Email verification is important when users sign in with the local account. However, for many social authentications, the incoming emailVerified will be true already.
Explained more in the article Email Verification with Firebase 3.0 SDK
What I did to work around this was use Zapier which has a built in API for firebase. It checks a location for added child elements. Then it takes the mail address and a verification url from the data of new nodes and sends them forwards. The url points back to my angular app, which sets the user email as verified.
As I host my app files in firebase, I don't need have to take care of any servers or processes doing polling in the background.
There is a delay, but as I don't block users before verifying mails it's ok. Zapier has a free tier and since I don't have much traffic it's a decent workaround for time being.
The new Firebase SDK v3 appears to support email address verification, see here (put your own project id in the link) but it doesn't appear to be documented yet.
I have asked the question on SO here
See #SamQuayle's answer there with this link to the official docs.
As noted by various others Firebase does now support account related emails but even better, as of 10 days ago or so it also supports sending any kind of email via Firebase Functions. Lots of details in the docs and example code here.
I used following code to check the email verification after creating new account.
let firAuth = FIRAuth.auth()
firAuth?.addAuthStateDidChangeListener { auth, user in
if let loggedUser = user {
if loggedUser.emailVerified == false {
loggedUser.sendEmailVerificationWithCompletion({ (error) in
print("error:\(error)")
})
}
else {
print(loggedUser.email)
}
} else {
// No user is signed in.
print("No user is signed in.")
}
}
I used MandrillApp. You can create an API key that only allows sending of a template. This way even thought your key is exposed it can't really be abused unless someone wants to fire off tonnes of welcome emails for you.
That was a hack to get myself off the ground. I'm now enabling CORS from a EC2 that uses the token to verify that the user exists before extending them a welcome via SES.

Multiple required auth strategies for hapi.js?

I have a hapi server that saves login credentials to a session cookie using the node module 'hapi-auth-cookie'. I'm using 'bell' to allow certain features to be authenticated with Facebook.
In the handler for the Facebook authentication, how do I access session info from the session cookie while still being able to access information bell provides me from Facebook?
there's an issue within the bell repository with a proposed solution to use server.auth.test(). Like this:
request.server.auth.test('strategy-name', request, (err, credentials) => {
if (err) {
// tested strategy didn't find a user
return reply({ error: 'Cannot find your credentials' })
}
//there is a user :)
return reply({ status: true, user: credentials.name })
})
Hope that helps and gives a direction :)

Google packaged app - identity API - removeCachedAuthToken

[google chrome 28]
I am using chrome.experimental.identity API in a packaged app and getAuthToken works fine - get's token with which I can get user info, etc.
I understand that the identity API is moving out from being experimental to the trunk so as from chrome 29 I will be able to use chrome.identity and remove "experimental" permission from my manifest.
Q: If I want to make a logout button is removeCachedAuthToken the way to go about it? I tried to use it in the experimental.identity but it does nothing.
To revoke token use this function from google sample app.
function revokeToken() {
user_info_div.innerHTML = "";
chrome.identity.getAuthToken({ interactive: false },
function (current_token) {
if (!chrome.runtime.lastError) {
// #corecode_begin removeAndRevokeAuthToken
// #corecode_begin removeCachedAuthToken
// Remove the local cached token
chrome.identity.removeCachedAuthToken({token: current_token}, function(){});
// #corecode_end removeCachedAuthToken
// Make a request to revoke token in the server
var xhr = new XMLHttpRequest();
xhr.open(
"GET",
"https://accounts.google.com/o/oauth2/revoke?token=" + current_token);
xhr.send();
// #corecode_end removeAndRevokeAuthToken
// Update the user interface accordingly
changeState(STATE_START);
sampleSupport.log("Token revoked and removed from cache. " +
"Check chrome://identity-internals to confirm.");
}
});
}
No. It is not the way to go.
removeCachedAuthToken is a function that removes a token acquired using getAuthToken from the internal token cache. However, it does not revoke the token. That means that the application will no longer be able to access to the user resources in current session, until it calls getAuthToken again. When that happens, it will be able to obtain a token again without the user needing to grant access.
As such, this function is not meant to be a logout related routine. It is more of a recovery mechanism, when you realize that the access token that your application is using is stale, or invalid in any other way. That happens, when you make a request using the access token and the HTTP response status is 401 Unauthorized. In that case you can scrap the token and then request a new one using getAuthToken. To simulate that behavior, you can revoke the a relevant grant using the Google Accounts page or form the diagnostic UI: chrome://identity-internals (currently it lists all of the cached tokens).
Please refer to the chrome app samples for GDocs and Identity.
(Pull requests 114 for GDocs and 115 for Identity in case you are doing that in next few days.)
I too struggled with this but I eventually discovered this solution buried in the Chrome App Samples. https://github.com/GoogleChrome/chrome-app-samples/blob/master/gapi-chrome-apps-lib/gapi-chrome-apps.js
removeCachedAuthToken removes it locally, but to revoke the token from Google servers you needs to send a request, hence the second part: xhr.open('GET', 'https://accounts.google.com/o/oauth2/revoke?token=' +
current_token);
Try this:
function revokeToken() {
chrome.identity.getAuthToken({ interactive: false },
function (current_token) {
if (!chrome.runtime.lastError) {
// #corecode_begin removeAndRevokeAuthToken
// #corecode_begin removeCachedAuthToken
// Remove the local cached token
chrome.identity.removeCachedAuthToken({token: current_token}, function(){});
// #corecode_end removeCachedAuthToken
// Make a request to revoke token in the server
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://accounts.google.com/o/oauth2/revoke?token=" +
current_token);
xhr.send();
// #corecode_end removeAndRevokeAuthToken
// Update the user interface accordingly
$("#revoke").get(0).disabled = true;
console.log("Token revoked and removed from cache. " +
"Check chrome://identity-internals to confirm.");
}
});
}