I am working on creating a next js application and have legacy user data I need to import from a word press site. The word press site had a signup with credential or a Facebook social login.
For the legacy data [credentials i.e email password] I wrote a script in [...nextauth.js] for logging in the user as follows.
CredentialsProvider({
name: 'Credentials',
credentials: {
email: { label: 'Email', type: 'email', placeholder: 'Email' },
password: {
label: 'Password',
type: 'password',
placeholder: 'Password',
},
},
async authorize(credentials, req) {
const len = 8;
const portable = true;
const phpversion = 9;
const hasher = new PasswordHash(portable, phpversion);
const encrypted_input = hasher.HashPassword(credentials.password);
await db.connect();
const user_raw = await LegacyUser.findOne({ email: credentials.email });
const user = JSON.parse(JSON.stringify(user_raw));
console.log(user.password);
await db.disconnect();
const valid = hasher.CheckPassword(credentials.password, user.password);
if (valid) {
console.log(user);
console.log('validPassword');
return user;
} else {
console.log('Passwords dont match');
return null;
}
},
})
Where db is the connection defined for all reads and writes to the mongo db and LegacyUser is the mongoose model defined. I test it out and so far so good.
Now I need to store the user session in the same db so I define database as the .env mongodb uri like bellow, including the mongodb adapter as in the documentation of next-auth:
adapter: MongoDBAdapter(clientPromise),
database: process.env.MONGODB_URI,
Now when I try to sign in again with the legacy password I don't get signed in and unfortunately I have no errors to show.
Only to point out that the console.log('validPassword'); of the CredentialsProvider does come through successfully.
I have been stuck on this issue for a few days, so any help is greatly appreciated.
Many thanks
Related
So, I've been working on a bot and I've been stuck on this issue where my bot is not able to connect to the community server
Here is this code I've used:
const SteamUser = require('steam-user');
const steam = new SteamUser();
steam.logOn({
accountName: '',
password: ''
});
steam.on('loggedOn', () => {
console.log('We joinned steam');
steam.setPersona(SteamUser.EPersonaState.Online); // Makes steam online
steam.gamesPlayed(730); // Opens csgo
});
Is there any fixes?
I tried some fixing to the code using ChatGPT but I still get error
Here is the code provided by ChatGPT:
const { SteamClient } = require('steam-client');
const SteamUser = require('steam-user');
// Create a new Steam client and user objects
const client = new SteamClient();
const user = new SteamUser(client);
// Set your Steam username and password
const username = 'your_username';
const password = 'your_password';
// Authenticate with the Steam client
user.logOn({
accountName: username,
password: password
});
client.on('logOnResponse', () => {
console.log('Logged in to Steam!');
// Join a community server
client.joinCommunityServer('123.456.789.012', 27015);
console.log('Joined community server!');
// Disconnect from the server after 10 seconds
setTimeout(() => {
client.leaveCommunityServer();
console.log('Disconnected from community server.');
}, 10000);
});
I am newbie in expressjs and read a very popular MERN project now.After an user(buyer) log into site and place an order which will be added into Mongodb tagged with the user(buyer),the backend code like below:
const addOrderItems = asyncHandler(async (req, res) => {
const {
orderItems,
shippingAddress,
paymentMethod,
itemsPrice,
taxPrice,
shippingPrice,
totalPrice,
} = req.body
if (orderItems && orderItems.length === 0) {
res.status(400)
throw new Error('No order items')
return
} else {
const order = new Order({
orderItems,
user: req.user._id,
shippingAddress,
paymentMethod,
itemsPrice,
taxPrice,
shippingPrice,
totalPrice,
})
const createdOrder = await order.save()
res.status(201).json(createdOrder)
}
})
Link:https://github.com/bradtraversy/proshop_mern/blob/master/backend/controllers/orderController.js
But where the req.user._id comes from?I check the whole project,some popular backend session or storage tools like express-session and cookie-sessiondid not installed and used.
It's comes from passport package. It will log user with JWT and populate the user property of the req object.
I want to register a user of the application through a REST API. I have already enrolled the admin and a user through the enrollAdmin.js and registerUser.js function but I want to call these functions through the node SDK and register users dynamically with there username (UUID) so that it's completly anonymous.
As the username I want to create a unique UUID and save that in the world state but also save that UUID on an off-chain database together with the personal information like password and name so that I can associate the personal information with the UUID.
Right know I'm confused by all the different steps I have to do to register a new user:
In what order do I have to enroll and register the user and should they all be defined in the express API or in chaincode?
This is my first approach of creating the REST Api and till now I have only defined the layout, the connection profile and wallet.
I would appreciate if somebody could help me implement the registration process in the express REST API so that an Identity for the UUID gets saved in the world state.
Thanks in advance.
server.js
'use strict';
var express = require('express');
var bodyParser = require('body-parser');
var app = express();
// Setting for Hyperledger Fabric
const { Wallets, FileSystemWallet, Gateway } = require('fabric-network');
const path = require('path');
const fs = require('fs');
const channelName = 'mychannel';
const mspOrg1 = 'Org1MSP';
const walletPath = path.join(__dirname, '..', 'wallet');
const ccpPath = path.resolve(__dirname, '..', 'connection-org1.json');
//register
app.post('/api/register', async function (req, res) {
try{
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
} catch (error) {
}
});
//login
app.post('/api/login', async function (req, res) {
try{
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = new FileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
} catch (error) {
}
});
app.listen(3000, ()=>{
console.log("***********************************");
console.log("API server listening at localhost:3000");
console.log("***********************************");
});
The process of how you want it to be is simple. In the middle, the off-chain database is used as a mapping table. I wrote only the core process logic.
/api/v1/register
validation check
Validate that the user's id is unique, that the required information value is missing, that the regular expression is correct, and that there is no wrong information.
generate random UUID
Create a random, unique uuid first. npm/uuid
const UUID = uuid.v4();
register/enroll user to fabric-ca
Perform the registration process as a user of the fabric. The information that goes into this process is UUID, and the user's information will not be stored in the blockchain.
fabricUser is a newly created class, and returns the result after fabric user registration and enroll process are performed by the Enroll method.
enrollment = await fabricUser.Enroll(UUID);
await wallet.put(enrollment);
insert to database
While saving the user information in the database, map it by storing the UUID created above.
The database was created as an example, assuming mongodb.
db.collection('User').insertOne({
'uuid': UUID,
'user_id': <input_user_id>,
...
});
/api/v1/login
The login process is as follows.
I don't know what authentication/authentication method you want to use, so I'll assume a token authentication method based on auth 2.0.
Verify the validity of the necessary information required for login and whether there is any incorrect information.
get UUID
generateAuthToken is a new function that generates JWT.
let res = await db.collection("User").findOne({'user_id': `<input_user_id>` });
return generateAuthToken(res.uuid);
/api/v1/invoke
Fabric resource request process is as follows.
Token validation and resource authorization check
get userName from token
getPayload is a function that gets the payload value located at the 1st index from the token.
const rawPayload = getPayload(token);
const jsonPayload = JSON.parse(rawPayload);
return jsonPayload
get wallet & invoke chaincode
The fabricChaincode is a function that wraps the invoke process of fabric-sdk. It is a function that executes invoke by inputting identity, chaincode information, and parameters, and returns a result.
const user = await db.collection("User").findOne({'user_id': jsonPayload.user_id });
const fabricIdentity = await wallet.get(user.uuid);
const res = fabricChaincode.invoke(fabricIdentity, `<your_chaincode_info>`, `<input_chaincode_params>`)
return res;
[EDIT]
Add it for your understanding.
fabricUser.js
/*
* Copyright IBM Corp. All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/
'use strict';
const { Wallets } = require('fabric-network');
const FabricCAServices = require('fabric-ca-client');
const fs = require('fs');
const path = require('path');
async function Enroll(user_id) {
try {
// load the network configuration
const ccpPath = path.resolve(__dirname, '..', '..', 'test-network', 'organizations', 'peerOrganizations', 'org1.example.com', 'connection-org1.json');
const ccp = JSON.parse(fs.readFileSync(ccpPath, 'utf8'));
// Create a new CA client for interacting with the CA.
const caURL = ccp.certificateAuthorities['ca.org1.example.com'].url;
const ca = new FabricCAServices(caURL);
// Create a new file system based wallet for managing identities.
const walletPath = path.join(process.cwd(), 'wallet');
const wallet = await Wallets.newFileSystemWallet(walletPath);
console.log(`Wallet path: ${walletPath}`);
// Check to see if we've already enrolled the user.
const userIdentity = await wallet.get(user_id);
if (userIdentity) {
console.log(`An identity for the user ${user_id} already exists in the wallet`);
return;
}
// Check to see if we've already enrolled the admin user.
const adminIdentity = await wallet.get('admin');
if (!adminIdentity) {
console.log('An identity for the admin user "admin" does not exist in the wallet');
console.log('Run the enrollAdmin.js application before retrying');
return;
}
// build a user object for authenticating with the CA
const provider = wallet.getProviderRegistry().getProvider(adminIdentity.type);
const adminUser = await provider.getUserContext(adminIdentity, 'admin');
// Register the user, enroll the user, and import the new identity into the wallet.
const secret = await ca.register({
affiliation: 'org1.department1',
enrollmentID: user_id,
role: 'client'
}, adminUser);
const enrollment = await ca.enroll({
enrollmentID: user_id,
enrollmentSecret: secret
});
const x509Identity = {
credentials: {
certificate: enrollment.certificate,
privateKey: enrollment.key.toBytes(),
},
mspId: 'Org1MSP',
type: 'X.509',
};
await wallet.put(user_id, x509Identity);
console.log(`Successfully registered and enrolled admin user ${user_id} and imported it into the wallet`);
} catch (error) {
console.error(`Failed to register user ${user_id}: ${error}`);
process.exit(1);
}
}
module.exports = {
Enroll
}
api.js
const uuid = require('uuid');
const fabricUser = require('./fabricUser);
const UUID = uuid.v4();
let res = await fabricUser.Enroll(UUID);
console.log(res);
I am learning to use mongoDB AND ExpressJS by building a Rest API that I would use with ReactJS.
I have always chosen MySQL for the management of my database, but the mongoDB database is not relational and it is still difficult for me to understand.
An example of what I want to do
Let's say that I have created a blog and want to get all the articles from a user logged in with an account.
All these operations are managed with a REST API and MongoDB.
How to create a OneToMany relationship between articles and a user.
With MySQL I just had to specify a user_id key for each article in an article table.
But with mongoDB how to create this and especially for a user who is logged in with an account, so that only a logged in user can view his articles.
EDIT
I have tried something, it works but I don't know if it's the right approach.
Context:
I made a REST API with NodeJS and ExpressJS.
The API will allow a user to organize their applications to facilitate the search for a job.
A user must create an account and log in to take advantage of all of the application's features, so no information is publicly available.
For registration and authentication of a user, I use PassportJS, mongoConnect and ExpressSession
To start, the User model of mongoDB
const userSchema = mongoose.Schema({
name: {
type:String
},
email: {
type:String,
required:true,
unique:true
},
email_is_verified: {
type:Boolean,
default:false
},
password: {
type:String,
},
referral_code : {
type:String,
default: function() {
let hash = 0;
for(let i=0; i < this.email.length; i++){
hash = this.email.charCodeAt(i) + ((hash << 5) - hash);
}
let res = (hash & 0x00ffffff).toString(16).toUpperCase();
return "00000".substring(0, 6 - res.length) + res;
}
},
referred_by : {
type: String,
default:null
},
third_party_auth: [ThirdPartyProviderSchema],
date: {
type:Date,
default: Date.now
}
},
{ strict: false }
);
module.exports = mongoose.model('Users', userSchema);
The Apply model represents an apply for a job, for now there is only the title.
To create the OneToMany relationship, I add a User field which refers to my User model
Function to retrieve all applies, so I retrieve the user id of the session.
const applySchema = mongoose.Schema({
title: { type:String, required:true },
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "User"
}
})
module.exports = mongoose.model('Apply', applySchema);
I created a controller for the management of a user's applies
exports.getAllApplies = (req, res, next) => {
res.locals.currentUser = req.user;
const userId = res.locals.currentUser.id
Apply.find({ user:userId })
.then(applies => res.status(200).json({ message:'success',
applies:applies }))
.catch(error => res.status(400).json({ error:error, message: 'Failed'}))
}
Function allowing to consult an apply
exports.getOneApply = (req, res, next) => {
res.locals.currentUser = req.user;
const userId = res.locals.currentUser.id
Apply.findOne({ _id:req.params.id, user:userId })
.then(apply => res.status(200).json({ message: `Apply with id
${apply._id} success`, apply:apply}))
.catch(error => res.status(500).json({ error:error, message:'Failed'}))
}
The routes of my api, I add an auth middleware to allow requests only for a user with a token
const express = require('express');
const router = express.Router();
const auth = require('../middleware/auth');
const applyCtrl = require('../controllers/apply');
router.get('/', auth, applyCtrl.getAllApplies);
router.get('/:id', auth, applyCtrl.getOneApply);
module.exports = router;
I apologize for the length of the post, if you have any questions, I would be happy to answer them.
Thank you in advance for your help and your answers.
I want to add an avatar in the user registration, but I don't know how, Please can someone share with me a full example (form, JS front, and JS backend). I'm using SailsJS 1.0 (the stable version) with VueJs.
Thanks in advance .
I figured it out. Watch these platzi tutorials:
https://courses.platzi.com/classes/1273-sails-js/10757-uploading-backend-file/
https://courses.platzi.com/classes/1273-sails-js/10758-uploading-frontend-files/
https://courses.platzi.com/classes/1273-sails-js/10759-downloading-files/
Here is what the videos tell you to do:
npm i sails-hook-uploads.
In api/controllers/entrance/signup.js
Above inputs key add a new key/value of files: ['avatar'],
In the inputs add:
avatar: {
type: 'ref',
required: true
}
In the body of the fn find var newUserRecord and above this add (even if avatar is not required, make sure to do this line, otherwise you will have a "timeout of unconsuemd file stream":
const avatarInfo = await sails.uploadOne(inputs.avatar);
Then in the first argument object of var newUserRecord = await User.create(_.extend({ add:
avatarFd: avatarInfo.fd,
avatarMime: avatarInfo.type
In api/models/User.js, add these attributes to your User model:
avatarFd: {
type: 'string',
required: false,
description: 'will either have "text" or "avatarFd"'
},
avatarMime: {
type: 'string',
required: false,
description: 'required if "avatarFd" provided'
},
Then create a download endpoint, here is how the action would look for it:
const user = await User.findOne(id);
this.res.type(paste.photoMime);
const avatarStream = await sails.startDownload(paste.photoFd);
return exits.success(avatarStream);
Add to the routes a route for this download avatar endpoint.
Then you can display this avatar by pointing the <img src=""> the source in here to this download endpoint.
------APPENDIX-----
----signup.js-----
module.exports = {
friendlyName: 'Signup',
description: 'Sign up for a new user account.',
extendedDescription:
`This creates a new user record in the database, signs in the requesting user agent
by modifying its [session](https://sailsjs.com/documentation/concepts/sessions), and
(if emailing with Mailgun is enabled) sends an account verification email.
If a verification email is sent, the new user's account is put in an "unconfirmed" state
until they confirm they are using a legitimate email address (by clicking the link in
the account verification message.)`,
files: ['avatar'],
inputs: {
emailAddress: {
required: true,
type: 'string',
isEmail: true,
description: 'The email address for the new account, e.g. m#example.com.',
extendedDescription: 'Must be a valid email address.',
},
password: {
required: true,
type: 'string',
maxLength: 200,
example: 'passwordlol',
description: 'The unencrypted password to use for the new account.'
},
fullName: {
required: true,
type: 'string',
example: 'Frida Kahlo de Rivera',
description: 'The user\'s full name.',
},
avatar: {
}
},
exits: {
success: {
description: 'New user account was created successfully.'
},
invalid: {
responseType: 'badRequest',
description: 'The provided fullName, password and/or email address are invalid.',
extendedDescription: 'If this request was sent from a graphical user interface, the request '+
'parameters should have been validated/coerced _before_ they were sent.'
},
emailAlreadyInUse: {
statusCode: 409,
description: 'The provided email address is already in use.',
},
},
fn: async function (inputs) {
var newEmailAddress = inputs.emailAddress.toLowerCase();
// must do this even if inputs.avatar is not required
const avatarInfo = await sails.uploadOne(inputs.avatar);
// Build up data for the new user record and save it to the database.
// (Also use `fetch` to retrieve the new ID so that we can use it below.)
var newUserRecord = await User.create(_.extend({
emailAddress: newEmailAddress,
password: await sails.helpers.passwords.hashPassword(inputs.password),
fullName: inputs.fullName,
tosAcceptedByIp: this.req.ip,
avatarFd: avatarInfo.fd,
avatarMime: avatarInfo.type
}, sails.config.custom.verifyEmailAddresses? {
emailProofToken: await sails.helpers.strings.random('url-friendly'),
emailProofTokenExpiresAt: Date.now() + sails.config.custom.emailProofTokenTTL,
emailStatus: 'unconfirmed'
}:{}))
.intercept('E_UNIQUE', 'emailAlreadyInUse')
.intercept({name: 'UsageError'}, 'invalid')
.fetch();
// If billing feaures are enabled, save a new customer entry in the Stripe API.
// Then persist the Stripe customer id in the database.
if (sails.config.custom.enableBillingFeatures) {
let stripeCustomerId = await sails.helpers.stripe.saveBillingInfo.with({
emailAddress: newEmailAddress
}).timeout(5000).retry();
await User.updateOne(newUserRecord.id)
.set({
stripeCustomerId
});
}
// Store the user's new id in their session.
this.req.session.userId = newUserRecord.id;
if (sails.config.custom.verifyEmailAddresses) {
// Send "confirm account" email
await sails.helpers.sendTemplateEmail.with({
to: newEmailAddress,
subject: 'Please confirm your account',
template: 'email-verify-account',
templateData: {
fullName: inputs.fullName,
token: newUserRecord.emailProofToken
}
});
} else {
sails.log.info('Skipping new account email verification... (since `verifyEmailAddresses` is disabled)');
}
// add to pubilc group
const publicGroup = await Group.fetchPublicGroup();
await Group.addMember(publicGroup.id, newUserRecord.id);
}
};