Is "logInWith" broken on parse-server when using GraphQL? - parse-server

I'm running parse-server 4.5.0 with the GrahQL configured. When I try to login with Facebook I'm getting an error "This authentication method is unsupported". I did some digging into the internals of parse-server and it appears the authData is not getting read correctly. I edited GraphQL/loaders/usersMutations.js and put a console.log inside the logInWith function:
mutateAndGetPayload: async (args, context, mutationInfo) => {
try {
const {
fields,
authData
} = args;
const {
config,
auth,
info
} = context;
console.log('## CJB 1, authData: ', authData);
const parseFields = await (0, _mutation.transformTypes)('create', fields, {
className: '_User',
parseGraphQLSchema,
req: {
config,
auth,
info
}
});
const {
sessionToken,
objectId
} = await objectsMutations.createObject('_User', _objectSpread(_objectSpread({}, parseFields), {}, {
authData
}), config, auth, info);
context.info.sessionToken = sessionToken;
return {
viewer: await (0, _usersQueries.getUserFromSessionToken)(context, mutationInfo, 'viewer.user.', objectId)
};
} catch (e) {
parseGraphQLSchema.handleError(e);
}
}
And what gets printed to the console is this:
## CJB 1, authData: { facebook: { id: undefined, access_token: undefined } }
Here is what my request payload looks like:
{
"operationName": "PerformLogIn",
"query": "mutation PerformLogIn($email: String!, $userId: String!, $token: String!) {\n logInWith(\n input: {authData: {facebook: {id: $userId, access_token: $token}}, fields: {email: $email}}\n ) {\n viewer {\n sessionToken\n user {\n email\n id\n username\n __typename\n }\n __typename\n }\n __typename\n }\n}\n",
"variables": {
"email": "user#email.com",
"userId": "userId",
"token": "tokenvalue"
}
}
Any thoughts would be greatly appreciated.
To add more details, I tried passing this: input: {authData: {facebook: "foo"}}. And that prints out ## CJB 1, authData: { facebook: 'foo' }. So it seems like the GraphQL value is not being read correctly?

Holy cow...so the solution was to pass an entire object in the variables, not the individual strings. Here's what the final request looks like that worked:
{
"operationName": "PerformLogIn",
"query": "mutation PerformLogIn($email: String!, $authData: Object!) {\n logInWith(\n input: {authData: $authData, fields: {email: $email}}\n ) {\n viewer {\n sessionToken\n user {\n email\n id\n username\n __typename\n }\n __typename\n }\n __typename\n }\n}\n",
"variables": {
"email": "user#email.com",
"authData": {
"facebook": {
"id": "userId",
"access_token": "tokenvalue"
}
}
}
}

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.

How can I set Next-Auth callback url? and next-auth session return null

I want to set login, logout callback url.
So, I set the callback url like this.
//signIn
const signInResult = await signIn("credentials", {
message,
signature,
redirect: false,
callbackUrl: `${env.nextauth_url}`,
});
//signOut
signOut({ callbackUrl: `${env.nextauth_url}`, redirect: false });
But, When I log in, I look at the network tab.
api/auth/providers, api/auth/callback/credentials? reply with
callbackUrl(url) localhost:3000
It's api/auth/callback/credentials? reply.
It's api/auth/providers reply
and api/auth/session reply empty object.
When I run on http://localhost:3000, everything was perfect.
But, After deploy, the login is not working properly.
How can I fix the error?
I added [...next-auth] code.
import CredentialsProvider from "next-auth/providers/credentials";
import NextAuth from "next-auth";
import Moralis from "moralis";
import env from "env.json";
export default NextAuth({
providers: [
CredentialsProvider({
name: "MoralisAuth",
credentials: {
message: {
label: "Message",
type: "text",
placeholder: "0x0",
},
signature: {
label: "Signature",
type: "text",
placeholder: "0x0",
},
},
async authorize(credentials: any): Promise<any> {
try {
const { message, signature } = credentials;
await Moralis.start({
apiKey: env.moralis_api_key,
});
const { address, profileId } = (
await Moralis.Auth.verify({ message, signature, network: "evm" })
).raw;
if (address && profileId) {
const user = { address, profileId, signature };
if (user) {
return user;
}
}
} catch (error) {
console.error(error);
return null;
}
},
}),
],
pages: {
signIn: "/",
signOut: "/",
},
session: {
maxAge: 3 * 24 * 60 * 60,
},
callbacks: {
async jwt({ token, user }) {
user && (token.user = user);
return token;
},
async session({ session, token }: any) {
session.user = token.user;
return session;
},
async redirect({ url, baseUrl }) {
// Allows relative callback URLs
if (url.startsWith("/")) return `${baseUrl}${url}`;
// Allows callback URLs on the same origin
else if (new URL(url).origin === baseUrl) return url;
return baseUrl;
},
},
secret: env.nextauth_secret,
});

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

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

Query result doesn't give the list of items, but just an empty array [ ] in aws-amplify

I try to make a query to see the list of users. My custom lambda function (which I attached as policy) is as follows:
const aws = require('aws-sdk');
const ddb = new aws.DynamoDB();
exports.handler = async (event, context) => {
if (!event.request.userAttributes.sub) {
console.log("Error: No user was written to DynamoDB")
context.done(null, event);
return;
}
// Save the user to DynamoDB
const date = new Date();
const params = {
Item: {
'id': { S: event.request.userAttributes.sub },
'__typename': { S: 'User' },
'username': { S: event.userName },
'email': { S: event.request.userAttributes.email },
'createdAt': { S: date.toISOString() },
'updatedAt': { S: date.toISOString() },
},
TableName: process.env.USERTABLE,
}
try {
await ddb.putItem(params).promise();
console.log("Success");
} catch (e) {
console.log("Error", e);
}
context.done(null, event);
}
And the schema model is as follows:
type User #model
#auth(rules: [
{ allow: public, operations: [read]}
{ allow: owner }
])
{
id: ID!
username: String!
email: String!
}
Although there is one user in the dynamoDb, when I make a query by:
query listUsers {
listUsers {
items {
email
id
username
}
}
}
the result is as follows:
{
"data": {
"listUsers": {
"items": []
}
}
}
As can be seen, the array of "items" is empty, the items are not shown, when I look at the console dynamoDb table, I see user items with id, username and email values. But it should give the results, where do I make mistake? Meanwhile I am new on aws-amplify.

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);
};```