To link an anonymous user to a newly-created user via email&pass I use the following function linkAndRetrieveDataWithCredential
For some reason I get the following error:
__WEBPACK_IMPORTED_MODULE_12_firebase_app___default.a.auth(...).currentUser.linkAndRetrieveDataWithCredential is not a function
The function is documented in the official Firebase documentation on how to link an anonymous user.
https://firebase.google.com/docs/auth/web/anonymous-auth
background: I use React.js and hence install Firebase via NPM.
What am I doing wrong ?
My code:
//if the user is anonymous, then upgrade the anonymous user to be the email&pass user.
//get the Credential object
var credential = firebase.auth.EmailAuthProvider.credential(this.state.email, this.state.password);
//get the Credential object
firebase.auth().currentUser.linkAndRetrieveDataWithCredential(credential).then(function(usercred) {
var user = usercred.user;
console.log("Anonymous account successfully upgraded", user);
//the user was created. redirect to Home page
window.location.assign("/");
Apparently the function was deprecated.
the right solution is documented here:
Firebase Convert Anonymous User Account to Permanent Account Error
// (Anonymous user is signed in at that point.)
// 1. Create the email and password credential, to upgrade the
// anonymous user.
var credential = firebase.auth.EmailAuthProvider.credential(email, password);
// 2. Links the credential to the currently signed in user
// (the anonymous user).
firebase.auth().currentUser.linkWithCredential(credential).then(function(user) {
console.log("Anonymous account successfully upgraded", user);
}, function(error) {
console.log("Error upgrading anonymous account", error);
});
Related
Can someone help me understand how to add a permission to a MS-Graph API call?
I'm trying to create a new team/group but I'm getting a permission error. Obviously I need add the Team.Create permission if I want to create a Team. Which I did as seen in the image below
Here's the sample code where I tried to add the permission to the MSAL client request:
// Initialize Graph client
const client = graph.Client.init({
// Implement an auth provider that gets a token
// from the app's MSAL instance
authProvider: async (done) => {
try {
// Get the user's account
const account = await msalClient
.getTokenCache()
.getAccountByHomeId(userId);
let scope = process.env.OAUTH_SCOPES.split(',');
scope.push("Team.Create");
console.log("Added a extra permission request");
console.log("scope = " + scope);
if (account) {
// Attempt to get the token silently
// This method uses the token cache and
// refreshes expired tokens as needed
const response = await msalClient.acquireTokenSilent({
scopes: scope,
redirectUri: process.env.OAUTH_REDIRECT_URI,
account: account
});
console.log("\nResponse scope = " + JSON.stringify(response) + "\n");
// First param to callback is the error,
// Set to null in success case
done(null, response.accessToken);
}
} catch (err) {
console.log(JSON.stringify(err, Object.getOwnPropertyNames(err)));
done(err, null);
}
}
});
return client;
Then I get the following error:
The user or administrator has not consented to use the application with ID 'xxxxxxx'
named 'Node.js Graph Tutorial'. Send an interactive authorization request for this user and resource
I did give permissions to Team.Create in the Azure Active Directory, so how do I consent to this app gaining access? Note this code is the tutorial for learning Graph: https://learn.microsoft.com/en-us/graph/tutorials/node
Judging by the screenshot, you can't give admin consent to the permission as it is grayed out.
You'll need to try if you can grant user consent.
acquireTokenSilent won't work in this case since consent is needed.
You need to use one of the interactive authentication methods to trigger user authentication, at which time you can consent to the permission on your user's behalf.
In that sample specifically, you probably need to modify the scopes here: https://github.com/microsoftgraph/msgraph-training-nodeexpressapp/blob/08cc363e577b41dde4f6a72ad465439af20f4c3a/demo/graph-tutorial/routes/auth.js#L11.
And then trigger the /signin route in your browser.
Hi,
We have a .Net Core 2.0 app, with Azure AD authentication.
At the moment we have some users associated with the app that have been given a role for the app in the Azure AD, and are using policies to check authorisation. Due business requirements we want to open the app to any user on the company, so we only need to check that the user is authenticated.
As an experienced C# developer, I went to the controller that had the following code
[Authorize(Policy = PolicyNames.RequireLinecardsUser)]
public class LinecardController : Controller
{
//controller code here
}
and changed it to this
[Authorize]
public class LinecardController : Controller
{
//controller code here
}
and for may user, that still has the role of LinecardUser, it works. it can access the app (the main entry point is inside that controller). But when we tested it with a user that does not have a role in the app, it gets an access denied exception.
So next step we went into startup, and removed the authorisation configurations ( it only had 2 now unused policies).
public void ConfigureServices(IServiceCollection services)
{
try
{
services.AddDbContext(options =>
{
options.UseSqlServer(Configuration.GetConnectionString("LinecardsContext"), opt => opt.UseRowNumberForPaging());
});
services.AddAuthentication(options =>
{
options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultAuthenticateScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultChallengeScheme = OpenIdConnectDefaults.AuthenticationScheme;
options.DefaultSignInScheme = CookieAuthenticationDefaults.AuthenticationScheme;
options.DefaultForbidScheme = OpenIdConnectDefaults.AuthenticationScheme;
})
.AddCookie(options =>
{
options.AccessDeniedPath = "/Account/AccessDenied/";
options.LoginPath = "/Account/Login/";
})
.AddOpenIdConnect(options =>
{
configuration.GetSection("AzureAd").Bind(options);
});
services.AddAuthorization(options =>
{
options.AddPolicy(PolicyNames.RequireLinecardsUser,
policy =>
{
policy.AddRequirements(new LinecardsWebUserRequirement());
policy.RequireAuthenticatedUser(); // Adds DenyAnonymousAuthorizationRequirement
// By adding the CookieAuthenticationDefaults.AuthenticationScheme, if an authenticated
// user is not in the appropriate role, they will be redirected to a "forbidden" page.
policy.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme);
});
options.AddPolicy(PolicyNames.RequireLinecardsAdmin,
policy =>
{
policy.AddRequirements(new LinecardsWebAdminRequirement());
policy.RequireAuthenticatedUser(); // Adds DenyAnonymousAuthorizationRequirement
// By adding the CookieAuthenticationDefaults.AuthenticationScheme, if an authenticated
// user is not in the appropriate role, they will be redirected to a "forbidden" page.
policy.AddAuthenticationSchemes(CookieAuthenticationDefaults.AuthenticationScheme);
});
});
services.AddScoped();
services.RegisterTypes();
services.AddReact();
services.AddAutoMapper();
services.Configure(x => x.ValueCountLimit = 100000);
services.AddMvc();
}
catch (Exception ex)
{
Log.Error(ex, "Error happened on configuring services");
throw;
}
}
That means that in the previous code we removed the services.AddAuthentication(); block. Same result, users that have roles can access the app, users that don't cannot. (tried with the browser in anonymous mode too, to make sure no caching problems were in action here).
Finally we tried to change the RequireLinecardsUser policy, so it didn't have the policy.AddRequirements(new LinecardsWebUserRequirement()); line (and changed the controller to the original authorization line with the policy.
Once again, same results, works fine for me, access denied for users that don't have a role.
Am I missing something obvious? Something that changed in Core 2.0? Something Azure related?
Because every documentation that I found says that the [Authorize] annotation without any arguments should work and intended, and only verify that user is authenticated before allowing the code to procede...
As some of you may have noticed the app has a react frontend that I haven't touched, feel free to point any problems that may be related with that.
PPS: Sorry if the formatting is not up to standard, but it's my first question
After some more tests with this app, an exception pointed to Azure being the culprit for this.
On the app properties in Azure there is an option asking "User assignment required?". That particular setting was set to yes for this app.
Changing it to no solved the problem.
When I place the below in a React component that queries the user model I am able to get the entire user object as queried by graphQL including the id property:
console.log(this.props.data.user)
But when I try to access the id property from code:
console.log(this.props.data.user) // undefined
console.log(this.props.data.user.id)
// error cannot get property of undefined
My first guess is that this is a security feature; I am using Auth0 and Graphcool.
But I may just be going about this in a backwards way. If so, any help on accessing the user id in the correct manner would be appreciated.
Thanks
This is covered in the FAQ article on the logged in user.
Obtaining a Signed JWT with Auth0
The user query returns the currently authenticated user. So first we have to think about how the authenticated user is determined.
The current state-of-the-art is using verified JWT and passing them as the Authorization header.
After entering valid credentials in Auth0 Lock, it returns a JWT that is signed with your secret Auth0 key. This signed JWT is sent to the GraphQL server where we'll use your Auth0 key to verify it and if it belongs to a valid user, the request is authenticated.
Setting the Authorization Header with Apollo Client
So I suspect that you're simply not passing a valid Authorization header. With Apollo, you can use this to ensure passing the token if it is present. Note that we'll use local storage for storing the token from Auth0 Lock:
const networkInterface = createNetworkInterface({ uri: 'https://api.graph.cool/simple/v1/__PROJECT_ID__' })
// use the auth0IdToken in localStorage for authorized requests
networkInterface.use([{
applyMiddleware (req, next) {
if (!req.options.headers) {
req.options.headers = {}
}
// get the authentication token from local storage if it exists
if (localStorage.getItem('auth0IdToken')) {
req.options.headers.authorization = `Bearer ${localStorage.getItem('auth0IdToken')}`
}
next()
},
}])
const client = new ApolloClient({ networkInterface })
Check this Auth0 example code or the live demo to see how it works.
You might also be interested in this answer on authorization (permissions).
This question already has answers here:
Firebase kicks out current user
(19 answers)
Closed 6 years ago.
i'm using firebase 3.0.5
I want members to have the ability to register other members through their account. Is there a way to prevent firebase from auto-signing new registrants in using createUserWithEmailAndPassword?
https://firebase.google.com/docs/auth/web/password-auth#create_a_password-based_account
I'm sure I can find another way to do this, but not auto-signing them in would make things much much simpler for me.
EDIT:
when a new member is signed up via an existing member, a random password is created and emailed to the new member. the existing member never knows the new members password.
Use createUser instead of createUserWithEmailAndPassword
As documented here:
https://www.firebase.com/docs/web/api/firebase/createuser.html
Creates a new email / password user with the provided credentials.
This method does not authenticate the user. After the account is
created, the user may be authenticated with authWithPassword().
var ref = new Firebase("https://<YOUR-FIREBASE-APP>.firebaseio.com");
ref.createUser({
email: "bobtony#firebase.com",
password: "correcthorsebatterystaple"
}, function(error, userData) {
if (error) {
switch (error.code) {
case "EMAIL_TAKEN":
console.log("The new user account cannot be created because the email is already in use.");
break;
case "INVALID_EMAIL":
console.log("The specified email is not a valid email.");
break;
default:
console.log("Error creating user:", error);
}
} else {
console.log("Successfully created user account with uid:", userData.uid);
}
});
I want to check the current user's password in order to allow him to change his/her password.
According to the user model docs, the way to do this is using the user.hasPassword method, by I get a "is not a function" error.
https://docs.strongloop.com/display/LB/User#user-prototype-haspassword
There is no reference to this in the angular SDK docs, so I'm guessing this method is not avalable from angular. https://docs.strongloop.com/display/public/LB/AngularJS+JavaScript+SDK#AngularJSJavaScriptSDK-Authentication
Any clues on how to accomplish this?
Sorry if this is just semantics, but if you are using the built in User model, you don't ever "check a user's password," you check if they are authenticated with a valid authToken that is set in a header.
But if you are trying to change a user's password and requiring them to log in before changing it, you can also just call User.login() and verify that you get a success response from the API. Then use the new password and persist it by updating the User instance with an update or updateAttributes.
See https://apidocs.strongloop.com/loopback-sdk-angular/#user
Will look something like this (warning: quick writeup, not tested!):
User.login({email: $scope.email, password: $scope.oldPassword}, function(response){
// user login was valid, now update user with new password by user id
//
User.prototype$updateAttributes({id: response.user.id}, {password: $scope.newPassword},
function(response) {
// success
}, function(response) {
// fail
});
}, function(response) {
// login failed, send to login screen
});