How to get data from related table in 1:N relationship when login in Sequelize? - authentication

I have two tables, users and recyclings, which are 1:N relationship (one user have many recyclings, one recycling belongs to one user. When login, I also want to fetch user's recyclings, but it doesn't work when I try to use include. I get response, but without recyclings array.
Response should be like this:
{
"id": 2,
"name": "Bernt",
"surname": "Bjornson",
"vat": "78965412354",
"email": "bernt#mail.sv",
"password": "$2a$08$N02C/YMq0MO.b.eiEZVAc.7cmdb49X1yEPKrFy.8bWU9TsrGgcdfG",
"createdAt": "2022-08-22T10:04:07.454Z",
"updatedAt": "2022-08-22T10:04:07.454Z",
"recyclings": [
{
"id": 4,
"solvents": 0,
"acids": 5,
"createdAt": "2022-08-22T10:04:36.413Z",
"updatedAt": "2022-08-22T10:04:36.413Z",
"userId": 2
},
{
"id": 5,
"solvents": 0.4,
"acids": 77,
"createdAt": "2022-08-22T10:05:05.733Z",
"updatedAt": "2022-08-22T10:05:05.733Z",
"userId": 2
}
]
}
Here is login function in AuthController:
const db = require("../models");
const config = require("../config/auth.config");
const User = db.user;
const Role = db.role;
const Recycling = db.recyclings;
const Op = db.Sequelize.Op;
var jwt = require("jsonwebtoken");
var bcrypt = require("bcryptjs");
exports.signin = (req, res) => {
User.findOne({
where: {
email: req.body.email
}
}, {include: ["recyclings"]}) //HERE IS INCLUDE-doesn't work!
.then(user => {
if (!user) {
return res.status(404).send({ message: "User not found!" });
}
var passwordIsValid = bcrypt.compareSync(
req.body.password,
user.password
);
if (!passwordIsValid) {
return res.status(401).send({
accessToken: null,
message: "Password not correct!"
});
}
var token = jwt.sign({ id: user.id }, config.secret, {
expiresIn: 86400 // 24 hours
});
var authorities = [];
user.getRoles().then(roles => {
for (let i = 0; i < roles.length; i++) {
authorities.push("ROLE_" + roles[i].name.toUpperCase());
}
res.status(200).send({
id: user.id,
name: user.name,
surname: user.surname,
vat: user.vat,
email: user.email,
roles: authorities,
accessToken: token
});
});
})
.catch(err => {
res.status(500).send({ message: err.message });
});
};
I don't know how to incorporate getRecyclings() function with existing getRoles(). Can someone help me, please?

spelling error,
you import Recycling to your code
and use recyclings in to your find query include.
change it.and try again

Related

React Blitz.js 3rd party auth failing with passport-azure-ad

I'm attempting to swap the default auth scheme in Blitz.js with a passport-azure-ad scheme, using the OIDCStrategy. I'm getting an error that I'm not sure about and would appreciate any help! I've created a new file under src/pages/auth/openid.tsx and into inserted the following code:
import { passportAuth } from "#blitzjs/auth"
import { api } from "src/blitz-server"
import { OIDCStrategy } from "passport-azure-ad"
const users: Array<{ oid: string }> = []
var findByOid = function (oid, fn) {
console.log("failing")
for (var i = 0, len = users.length; i < len; i++) {
const user = users[i]
console.log("we are using user: ", user)
if (user && user.oid === oid) {
return fn(null, user)
}
}
return fn(null, null)
}
export default api(
passportAuth({
successRedirectUrl: "/",
errorRedirectUrl: "/",
strategies: [
{
strategy: new OIDCStrategy(
{
identityMetadata:
"https://login.microsoftonline.com/<tenant-nam>.onmicrosoft.com/v2.0/.well-known/openid-configuration",
clientID: <client-id>,
responseType: "code id_token",
responseMode: "form_post",
redirectUrl: "http://localhost:3000/auth/openid/callback",
allowHttpForRedirectUrl: true,
clientSecret: "<client-secret>",
validateIssuer: false,
passReqToCallback: true,
scope: ["profile", "offline_access", "https://graph.microsoft.com/mail.read"],
loggingLevel: "info",
nonceMaxAmount: 5,
useCookieInsteadOfSession: false,
cookieEncryptionKeys: [
{ key: "12345678901234567890123456789012", iv: "123456789012" },
{ key: "abcdefghijklmnopqrstuvwxyzabcdef", iv: "abcdefghijkl" },
],
},
function (iss, sub, profile, accessToken, refreshToken, done) {
if (!profile.oid) {
return done(new Error("No oid found"), null)
}
// asynchronous verification, for effect...
process.nextTick(function () {
findByOid(profile.oid, function (err, user) {
if (err) {
return done(err)
}
if (!user) {
// "Auto-registration"
users.push(profile)
return done(null, profile)
}
return done(null, user)
})
})
}
),
},
],
})
)
I believe the configuration is good because I can run the example from passport-azure-ad from the github examples. The only change I make is that I set redirectUrl: "http://localhost:3000/auth/openid/callback", instead of redirectUrl: ".../return", per the blitz.js third party auth documentation. The tenantname, client_id, client_secret are redacted but I do set them to the correct values. I have also verified that the app registration is correctly set with the correct redirect uri.
I run blitz dev and when I go to the http://localhost:3000/auth/openid route I get the following error.
Here is the console output that is produced:
As you can see there is a Module not found: Can't resolve './src/build', this error only occurs if I go to the auth/openid page but the app is able to load.

Retrieving auth0id using auth0-react-native-sample

I'm currently trying out Auth0 and messing around with a sample app:
https://github.com/auth0-samples/auth0-react-native-sample
I am trying to get hold of the user I am logging in as and getting the authId but what I'm getting in return is the client details:
const onLogin = () => {
auth0.webAuth
.authorize({
scope: 'openid profile email'
})
.then(credentials => {
const user = auth0.users(credentials.accessToken);
console.log(user);
Alert.alert('AccessToken: ' + credentials.accessToken);
setAccessToken(credentials.accessToken);
})
.catch(error => console.log(error));
};
Result:
{
"client": {
"telemetry": {
"name": "react-native-auth0",
"version": "2.14.1"
},
"baseUrl": "<BASE URL>",
"domain": "<DOMAIN>",
"bearer": "Bearer <TOKEN>",
"timeout": 10000
}
}
Is there any way to get a hold of the authId via this way?
Found a way to access it via this way:
auth0.auth.userInfo({token: credentials.accessToken}).then(result => {
console.log(result);
});

how to reference itself in mongoose schema?

I am trying to create profile of a user and in friends key I want to store array of objectId of other users. So how to reference itself
const mongoose = require("mongoose")
const userSchema = mongoose.Schema({
firstname:String,
lastname:String,
password:String,
email:{
type:String,
unique:true
},
birthday:Date,
creation_date:{
type:Date,
default:Date.now
},
gender:String,
profile_picture:{
type:String,
default:""
},
friends:[{
type:mongoose.Schema.Types.ObjectId,
ref:"userModel"
}]
})
const userModel = new mongoose.model("userModel", userSchema)
module.exports = userModel
By doing this, and sending request from postman i am getting empty array of friends
Fields
firstname
dhiran
lastname
sapkota
email
dhiransapkota9#gmail.com
password
thisisemail
birthday
2059-08-09
gender
male
friends
["6319b1bd2d4f0f0145662f3b", "6319ad712d4f0f0145662f35"]
Output I am getting is:
{
"success": true,
"msg": "user has been signed up",
"signupUser": {
"firstname": "dhiran",
"lastname": "sapkota",
"password": "$2a$10$rOaA3QlameBO4my8C9fmye73Zi9QxtPbi3X.XFpDNd7J8tBD3SbMq",
"email": "dhiransapkota999#gmail.com",
"birthday": "2059-08-09T00:00:00.000Z",
"gender": "male",
"profile_picture": "1662798667954-cv_image.png",
"friends": [],
"_id": "631c4b4c2d832a439c88720f",
"creation_date": "2022-09-10T08:31:08.072Z",
"__v": 0
}
}
I am using multipart/formdata so data is in this format.
route
router.post("/signup", upload.single("profile"), (req, res) => {
userControllerInstance.signup(req, res, profile_picture)
});
controller:
class UserController {
async signup(req, res, profile_picture) {
try {
const { firstname, lastname, email, password, birthday, gender, friends } =
req.body;
const response = await userModel.find({ email: email });
console.log(response);
if (response.length > 0) {
return res
.status(409)
.json({ success: false, msg: "email already exists" });
}
const hashedPassword = generateHash(password);
const signupUser = await userModel.create({
firstname,
lastname,
email,
password: hashedPassword,
birthday,
gender,
profile_picture,
friends
});
return res.json({
success: true,
msg: "user has been signed up",
signupUser,
});
} catch (error) {
return res.json(error);
}
}
}

How to resolve Cloud Function Error:401 Unauthorized

I have coded an Apps Script that creates an event in the Calendar.
Apps Script is stand alone, and event in also created in my personal Gmail account.
This Script is linked to GCP project linked to same account as Script.
Oauth consent screen is created in the GCP account and also credentials for Oauth2.0 client ID.
Now I created a cloud function to call this appsScript but it is giving an Error:401
following is code for the cloud function
let message = req.query.message || req.body.message || 'Hello World!';
const axios = require('axios');
const {google} = require('googleapis');
//Authorization
const { GoogleAuth } = require('google-auth-library');
const auth1 = new GoogleAuth({
keyFile: 'credentials.json',
scopes: ['https://www.googleapis.com/auth/drive','https://www.googleapis.com/auth/drive.metadata'
, 'https://www.googleapis.com/auth/calendar','https://www.googleapis.com/auth/calendar.events' ],
});
const drive = google.drive({version: 'v3', auth: auth1 });
const calendar = google.calendar({version : "v3"});
//calling formSchedule function with all the variables
async function formSchedule(eventDate,claimId, garageId, claimDet,startTime,cEmailG){
//Schedule Meeting Json Data
var evDurtion=30;
var startDateTime = startTime;
var endDateTime=new Date(startDateTime.getTime()+(evDurtion*60000));
// console.log(endDateTime)
var subject="Claim ID : "+claimId+' - Call';
var attendees=[{
"email": garageId,
},
];
var eventData={
"summary":subject,
'start': {
'dateTime': startDateTime,
'timeZone': 'Asia/Kolkata'
},
'end': {
'dateTime': endDateTime,
'timeZone': 'Asia/Kolkata'
},
"attendees":attendees,
"conferenceData": {
"createRequest": {
"conferenceSolutionKey": {
"type": "hangoutsMeet"
},
"status": {
"statusCode": "success"
},
"requestId": "test1235"
}
},
"description":claimDet,
"defaultReminders": [
{
"method": "popup",
"minutes": "5"
}
]
}
console.log("after all variables initialization")
// Schedule Meeting
axios({
method: "post",
url : //API Executable deployed Apps Script link,
data: {
'eventdata' : eventData,
'serviceId' : cEmailG
},
headers: {
'Content-Type': 'text/plain;charset=utf-8',
},
}).then(function (response) {
try{
console.log('Event Added Successfully.')
}
catch (error){
console.log('------error-----',error)
}
})
}
res.status(200).send(message);
};```

Mongoose populate()

referring to Mongoose url populate example given at https://mongoosejs.com/docs/populate.html#checking-populated , there seems to be a two way relationship between both Schema. What if I only have 1 way relationship for example ( using same schema example, But Person schema does not Story ref )
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const personSchema = Schema({
name: String,
age: Number
});
const storySchema = Schema({
author: { type: Schema.Types.ObjectId, ref: 'Person' },
title: String
});
const Story = mongoose.model('Story', storySchema);
const Person = mongoose.model('Person', personSchema);
How can I return a GET Story output that looks like the following :
{
author :{
name: "Bla bla bla",
age: 30
}
title : "ABC Story"
}
I am always getting this at the moment :
{
author :34235245453
title : "ABC Story"
}
I am not sure whether this is a good practise, but you can achieve this as follows
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const personSchema = Schema({
name: String,
age: Number
});
const storySchema = Schema({
author: Schema.Types.ObjectId, //modified by just defining the type
title: String
});
const Story = mongoose.model('Story', storySchema);
const Person = mongoose.model('Person', personSchema);
when populating,
SOMETHING.find()
.populate({
'path':'author',
'model':'Person'
});
I think you are confusing populated() function and populate() function.
To be able to retrieve the author info of a story, we need to use populate like this:
router.get("/stories/:id", async (req, res) => {
const result = await Story.findById(req.params.id).populate("author");
res.send(result);
});
Let's say we have this person:
{
"_id": "5e3c63ba3a178830dc497a00",
"name": "Name1",
"age": 33,
"__v": 0
}
And this story by user:
{
"_id": "5e3c63e93a178830dc497a02",
"author": "5e3c63ba3a178830dc497a00",
"title": "Story1",
"__v": 0
}
The result will be like this when we send a get request to our route ( http://.../stories/5e3c63f33a178830dc497a02)
{
"_id": "5e3c63e93a178830dc497a02",
"author": {
"_id": "5e3c63ba3a178830dc497a00",
"name": "Name1",
"age": 33,
"__v": 0
},
"title": "Story1",
"__v": 0
}
To get all stories with author info, we can use find() method like this:
router.get("/stories", async (req, res) => {
const result = await Story.find().populate("author");
res.send(result);
});