how secure is context in react? - reactjs

How secure is the context in react, I want to created a user from front end and set his indicial status to demo . later on when the user make a payment his status will change , bottom line is how secure this logic is could someone come and modify the initial set status to 'premium' ? so he could skip the payment part ?
const Signup = async (email: string, password: string, userType: string) => {
await createUserWithEmailAndPassword(auth, email, password)
.then((userCredential) => {
setDoc(doc(db, 'Data', userCredential.user.uid), {
user: userType,
verifiedEmail: false,
status: 'demo',
createdAt: Timestamp.now(),
});

As a rule of thumb and especially for single page applications which are rendered on the client side: Data from and (with)in clients can't and shouldn't be trusted as a security measurement.
So consider the context as "not secure" and always rely on proper permission management on the server side - so the worst thing which can happen is that your client may see the "premium" menus, but can't get anything out of it since the server denies any action.

Related

Linking Twitter account to user account (twitter-passport)

Currently, a user is able to login in and sign up for my application no problem. I've then added a "Link your twitter user to account" button which when clicked takes the user to '/auth/twitter'. This then kicks off passport-twitter and the oAuth process begins.
Right now, I'm using passport-twitter as the package for twitter oAuth. This process works. I'm able to get the user successfully authenticated. Here is the code.
However two problems: I don't see a way to 1) keep the user signed into Twitter so they don't have to keep doing this flow of reconnecting their twitter every time they want to push content to it from my app. and 2) associate the Twitter user and the signed in user to my application. Long term, I plan to add other social media accounts, so the user will have multiple social media linked. Twitter will be just one.
Problem #2: I wasn't able to do an axios.get call from my redux store or from the front end to '/auth/twitter/' otherwise I could then just get the information back from the call and then post it to the user's table (right?). So, instead I'm accessing '/auth/twitter' from an tag in the front end to kick off the flow.
passport.use(
new TwitterStrategy(
{
consumerKey: "XXX",
consumerSecret: "XXX",
callbackURL: "http://localhost:8080/auth/twitter/callback",
// callbackURL: "http://www.localhost:8080/home",
includeEmail: true,
},
async(accessToken, refreshToken, profile, cb) => {
console.log('got the prodile')
const twitterIDforOAuth = profile.id
const { id, username } = profile;
let theuser = await User.findOne({
where: {
twitterID: id
}
})
if(theuser){
console.log('FOUND USER', '\n', theuser)
} else {
try {
console.log('NO USER FOUND')
var passwordUser = (Math.random() + 1).toString(36).substring(7);
console.log('CREATING USER')
theuser = await Promise.all([
User.create({
twitterID: id,
username : username,
password: passwordUser
})
])
console.log('USER CREATED');
} catch (error) {
console.log(error);
}
}
//this callback calls the auth/callback url to kick off the redirect process
// need to send username and password to /auth/signup
return cb(null, {username: username, password: passwordUser})
//Line below sends too much data that is irrelevant for the user... lets review it?
// return cb(null, {username: twitterIDforOAuth})
}
)
);
app.get('/auth/twitter', passport.authenticate("twitter"));
app.get(
"/auth/twitter/callback",
passport.authenticate("twitter", {
failureRedirect: "/login",
failureMessage: true,
session: false
}),
async (req, res) => {
var user = req.user;
console.log(user.username, user.password);
//GET USERNAME AND PASSWORD
var username = user.username;
var password = user.password;
///they need to login the app
//auth/login
res.redirect('/AccountSettings')
}
);
The user is being redirected to /AccountSettings while they go through this flow, so I know that the user is 100% authenticated and signed in with Twitter (otherwise they'd be pushed to /login, which isn't happen).
Most people in this flow create a user in their database using the information returned from Twitter.
However, I'm trying to link this information to the signed in user, and keep them signed into Twitter so the user doesn't need to keep reconnecting their Twitter account (at least not often). (With access to their Twitter account, my plan is to allow them to push content to it)
Currently I'm hitting the '/auth/twitter' route with an tag which's href takes it to '/auth/twitter'. Is this the right way about it or is this approach causing my linkage issue?
What are people's recommendation for this issue? Whats the right way to approach linking social media accounts to a signed in user's account?
I'm using Express, Redux, React, Postgres, and passport-twitter
SOLUTION: How to passing data in TwitterStrategy, PassportJS?
had to create a state object outside the /auth/twitter route and then added a id param to the /auth/twitter route so the full route was /auth/twitter/:id
once I got the id I saved it to a state route outside the route in the server file that was accessible to the callback function later in the proces.

How do I avoid React Native GoogleSignIn by sending to google a password violation

I used #react-native-google-signin/google-signin": "^8.0.0" to create a google sign in button into my app.
When I used it, google recognised it as not trusted app, so send my an email to advice of a violation, and now every time I use a password saved on my google account to login on any site or application, he gives me a message telling me to change all of my passwords. I solved to remove the message, by ignoring for every passwords, almost 200 :/. But it's just temporary solution, cause if I do login again to my app it will happen again. How can I say to google that it is an app in developing, is there any mode to activate? Here's my code:
GoogleSignin.configure({
scopes: ['https://www.googleapis.com/auth/drive.readonly'], // what API you want to access on behalf of the user, default is email and profile
webClientId: '15299853035-njb79hdij6h1svo22drigurca1qb4djb.apps.googleusercontent.com', // client ID of type WEB for your server (needed to verify user ID and offline access)
offlineAccess: true, // if you want to access Google API on behalf of the user FROM YOUR SERVER
// hostedDomain: '', // specifies a hosted domain restriction
// forceCodeForRefreshToken: true, // [Android] related to `serverAuthCode`, read the docs link below *.
// accountName: '', // [Android] specifies an account name on the device that should be used
iosClientId: '15299853035-siujgcjtol0lfja83n7p6fk55cq6jinn.apps.googleusercontent.com', // [iOS] if you want to specify the client ID of type iOS (otherwise, it is taken from GoogleService-Info.plist)
// googleServicePlistPath: '', // [iOS] if you renamed your GoogleService-Info file, new name here, e.g. GoogleService-Info-Staging
// openIdRealm: '', // [iOS] The OpenID2 realm of the home web server. This allows Google to include the user's OpenID Identifier in the OpenID Connect ID token.
// profileImageSize: 120, // [iOS] The desired height (and width) of the profile image. Defaults to 120px
});
try {
await GoogleSignin.hasPlayServices();
const { idToken } = await (await GoogleSignin.signIn());
const googleCredential = await GoogleAuthProvider.credential(idToken);
await signInWithCredential(authApp, googleCredential)
.then(async(userCredential) => {
if(!authApp.currentUser.emailVerified)
{
sendEmailVerification(authApp.currentUser)
.then(() => {
// Email verification sent!
// ...
})
.catch((error)=>{
setLoading(false)
console.log(error)
})
}
......

How to update the password of a Supabase user on a NextJs project?

I'm facing an issue updating a password for a supabase user on a BlitzJs (NextJs) project.
Basically, I have a reset password method that works perfectly. First I send an email with a reset link, that opens a page where the user can update his password like so:
const { error, data } = await supabase.auth.api.updateUser(token, { password: password.trim() })
the token being the one in the url, provided in the email link.
So far, so good, but when I try to update the password for a logged in user, using the exact same method supabase.auth.api.updateUser, it fails to find the user;
The difference is the token is the session.access_token
So I've tried to use the supabase.auth.api.updateUserById method, but it gives me another error: { message: 'User not allowed', status: 401 }
Any ideas? I feel the supabase docs about this is not very clear, and probably outdated as it doesn't show all the available methods :/
Update password for authenticated user.
const { user, error } = await supabase.auth.update({password: 'new password'})
For more informations check: Supabase references

AWS Amplify phone number input validation - most practical method?

import Auth from '#aws-amplify/auth';
await Auth.signUp({
username,
password,
attributes: {email, phone_number: phoneNumber}
})
assume 'phoneNumber' is a user-dependent input.
many (most) inputs will cause failure.
What is the most practical method for validation of 'phoneNumber' prior to Auth.signUp ?
Additionally, why does failure manifest as such in React Native?:

aws-amplify forgot password function with react js sending SMS instead of email

I build an app using aws-amplify that allows login with Cognito users. However, Auth.forgotPassword seems to be sending SMS to mobile device instead of EMAIL. How can I change the behavior such that it sends an email?
Here are related code:
Auth.forgotPassword(this.state.username)
.then(data => this.setState({instruction: 'An email has been sent to your email with a temporary password.', usernameError: false, passwordError: false}))
.catch(err => this.setState({instruction: err.message, usernameError: false, passwordError: false}));
You can configure what you need to verify when forgotPassword API is triggered in the AWS Cognito Console.
Amazon Cognito > Manage User Pool > Choose your pool > General Settings > MFA and verifications > Which attributes do you want to verify?
Also when you trigger the ForgotPassword API you get CodeDeliveryDetails Object in response
const result = await Auth.forgotPassword(username);
console.log(result);
CodeDeliveryDetails: {
"AttributeName": "email",
"DeliveryMedium": "EMAIL",
"Destination": "n***#g***.com"
}
From the result, you get on which medium the code has been delivered and accordingly notify the user in the app.

Resources