Req. query doesn't pass - mongodb

I'm trying to pull data from a document containing a logged-in user from the MongoDB database. However, req. the query doesn't seem to pass.
case "GET": {
const { userName } = req.query;
const users = await db
.collection("USERS")
.find({ user: { $in: [userName] } })
.toArray();
res.json(users);
break;
}
export async function getStaticProps() {
const res = await fetch(`http://localhost:3000/api/usersAPI`, {
method: "GET",
headers: {
"Content-Type": "application/json",
},
});
let users = await res.json();
return {
props: { users },
};
}

Related

Next-Auth CredentialsProvider really slow

The following works fine, but I have noticed that it is really slow login in a client. How can I make it faster?
import NextAuth from "next-auth"
import CredentialsProvider from "next-auth/providers/credentials"
import { ObjectId } from 'mongodb'
import { MongoDBAdapter } from "#next-auth/mongodb-adapter"
import clientPromise from "../../../lib/mongodb";
import { v4 as uuidv4 } from 'uuid';
var CryptoJS = require("crypto-js");
const sFinder = async (task, token) => {
try{
const client = await clientPromise;
const database = client.db('DRN1');
const ses = await database.collection('sessions');
switch (task) {
case 1:
const result = await ses.find({
"userId": ObjectId(token.uuid)
}).sort({"_id":-1}).limit(1).toArray();
if (!result) {
return 202;
}
else{
return result[0].sessionToken
}
break;
case 2:
const insertResult = await ses.insertOne({"userId":token.uuid, "sessionToken":token.accessToken});
if (!insertResult) {
return 203;
}
else{
return insertResult
}
break;
case 3:
var expdate = new Date(token.exp * 1000);
const UpdateResult = await ses.updateOne({"userId":ObjectId(token.uuid), "sessionToken":token.accessToken},
{ $set: {"expires": expdate}}, { upsert: true });
if (!UpdateResult) {
return 203;
}
else{
return UpdateResult
}
break;
default:
break;
}
} catch(e){
console.error(e);
}
}
export default NextAuth({
adapter: MongoDBAdapter(clientPromise),
session: {
strategy: 'jwt',
jwt: true,
},
providers: [
CredentialsProvider({
name: 'DRN1',
credentials: {
username: { label: "Username", type: "text"},
password: { label: "Password", type: "password" }
},
async authorize(credentials, req) {
try{
const client = await clientPromise;
const database = client.db('DRN1');
const users = await database.collection('users');
const result = await users.findOne({
username: credentials.username,
});
if (!result) {
throw new Error('No user found with the username');
}
var bytes = CryptoJS.AES.decrypt(result.password, process.env.PASS_ENC);
var decryptedData = bytes.toString(CryptoJS.enc.Utf8);
//Check hased password with DB password
if(decryptedData != credentials.password){
throw new Error('Password doesnt match');
}
return {uuid:result._id, username: result.username, email: result.email, type:result.type, "sessionID":uuidv4()};
} catch(e){
console.error(e)
}
}
})
],
callbacks: {
signIn: async ({ user, account, profile, email, credentials }) => {
account.accessToken = user.sessionID
account.uuid = user.uuid
const test = await sFinder(2,account)
return true
},
jwt: async ({ token, account }) => {
if (account) {
token.uuid = account.uuid
token.accessToken = account.accessToken
}
const lastUsedToken = await sFinder(1,token)
const updateTokenExpire = await sFinder(3,token)
if(lastUsedToken != token.accessToken){
// console.log("I have made it an error")
token.error = 555;
}
return token
},
session: async ({ session, token, user }) => {
session.uuid = token.uuid
if(!token.accessToken){
//OAUTH Accounts
session.accessToken = uuidv4()
}else{
session.accessToken = token.accessToken
}
if(token.error == 555){
session.error = 555
}
return session
}
},
pages:{
error: 'signin'
},
theme: {
colorScheme: "dark", // "auto" | "dark" | "light"
brandColor: "", // Hex color code
logo: "https://storage.googleapis.com/radiomedia-images/station_logos/v2/DRN1_small.png" // Absolute URL to image
}
});
I believe what is slowing it down is the following
callbacks: {
signIn: async ({ user, account, profile, email, credentials }) => {
account.accessToken = user.sessionID
account.uuid = user.uuid
const test = await sFinder(2,account)
return true
},
jwt: async ({ token, account }) => {
if (account) {
token.uuid = account.uuid
token.accessToken = account.accessToken
}
const lastUsedToken = await sFinder(1,token)
const updateTokenExpire = await sFinder(3,token)
if(lastUsedToken != token.accessToken){
// console.log("I have made it an error")
token.error = 555;
}
return token
},
session: async ({ session, token, user }) => {
session.uuid = token.uuid
if(!token.accessToken){
//OAUTH Accounts
session.accessToken = uuidv4()
}else{
session.accessToken = token.accessToken
}
if(token.error == 555){
session.error = 555
}
return session
}
},
Mainly all the awaits, but the await functions are to make sure the user is not login on another device. As we log the old devices out automatically.

Prisma: how to write transaction where results from one query are used by another query

I'm working on a project with Next.js and Prisma. In one of my API routes, I have a three queries. The results of the first and second queries are used in the third query. I'd like to do all three operations as a transaction and then return the data from the first query in the response.
I'm familiar with using prisma.$transaction but I don't know how to write it in this case where results #1 and #2 are used by query #3. Here are the queries as they are written now. Thanks in advance!
const { boardId } = req.body
const { description, status, title } = req.body.task
const createTask = await prisma.task.create({
data: {
board: boardId,
description,
status,
title
}
})
const statusArray = await prisma.board.findUnique({
where: {
id: boardId
},
select: {
[status]: true
}
})
const updateBoardStatusArray = await prisma.board.update({
where: {
id: boardId
},
data: {
[status]: {
set: [...statusArray[status], createTask.id]
}
}
})
// return data from first query
res.status(201).json({task: createTask})
Here you go:
const { boardId } = req.body;
const { description, status, title } = req.body.task;
const [createTask] = await prisma.$transaction(async (prisma) => {
const createTask = await prisma.task.create({
data: {
board: boardId,
description,
status,
title,
},
});
const statusArray = await prisma.board.findUnique({
where: {
id: boardId,
},
select: {
[status]: true,
},
});
const updateBoardStatusArray = await prisma.board.update({
where: {
id: boardId,
},
data: {
[status]: {
set: [...statusArray[status], createTask.id],
},
},
});
return [createTask, statusArray, updateBoardStatusArray];
});
// return data from first query
res.status(201).json({ task: createTask });
You can learn more about Interactive Transaction here

How to decrease the value/ quantity of something using a button in mongodb and website together

I am trying to decrease the quantity of something by 1 in both mongodb and website together. I have already used an update option to change the quantity. Now I need to only decrease it by 1.
const handleRestockItems = (event) => {
event.preventDefault();
const quantity = event.target.quantity.value;
const RestockItem = { quantity };
// send data to the server
const url = `http://localhost:5000/item/${itemId}`;
fetch(url, {
method: "PUT",
headers: {
"content-type": "application/json",
},
body: JSON.stringify(RestockItem),
})
.then((res) => res.json())
.then((data) => {
console.log("success", data);
alert("Restock Items successfully!!!");
event.target.reset();
// Adding reload button to show updated items on UI
window.location.reload(false);
});
};
MongoDB code:
app.put("/item/:id", async (req, res) => {
const id = req.params.id;
const updatedUser = req.body;
const filter = { _id: ObjectId(id) };
const options = { upsert: true };
const updatedDoc = {
$set: {
quantity: updatedUser.quantity,
},
};
const result = await iCollection.updateOne(filter, updatedDoc, options);
res.send(result);
});

NextAuth - AccessToken not refreshed with MongoDB and Coinbase

I have a problem with my authentication via Coinbase (using Nextauth) on NextJS app.
I made this code below, and it saves the profile well in my Mongodb database. But when I re-login, accesstoken and refreshtoken are not changed...
So I can’t use the APIs afterwards.
import NextAuth from 'next-auth';
import Providers from 'next-auth/providers';
async function refreshAccessToken(token) {
try {
const url =
"https://api.coinbase.com/oauth/token?" +
new URLSearchParams({
client_id: process.env.COINBASE_CLIENT_ID,
client_secret: process.env.COINBASE_SECRET_ID,
grant_type: "refresh_token",
refresh_token: token.refreshToken,
})
const response = await fetch(url, {
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
method: "POST",
})
const refreshedTokens = await response.json()
if (!response.ok) {
throw refreshedTokens
}
return {
...token,
accessToken: refreshedTokens.access_token,
accessTokenExpires: Date.now() + refreshedTokens.expires_in * 1000,
refreshToken: refreshedTokens.refresh_token ?? token.refreshToken, // Fall back to old refresh token
}
} catch (error) {
console.log(error)
return {
...token,
error: "RefreshAccessTokenError",
}
}
}
export default NextAuth({
// Configure one or more authentication providers
providers: [
Providers.Coinbase({
clientId: process.env.COINBASE_CLIENT_ID,
clientSecret: process.env.COINBASE_SECRET_ID,
callbackUrl: process.env.COINBASE_CALLBACKURL,
scope: "wallet:accounts:read",
}),
],
callbacks: {
async jwt({ token, user, account, profile, isNewUser }) {
// Initial sign in
if (account && user) {
return {
accessToken: user.data.access_token,
accessTokenExpires: Date.now() + user.data.expires_in * 1000,
refreshToken: user.data.refresh_token,
user,
}
}
// Return previous token if the access token has not expired yet
if (Date.now() < token.accessTokenExpires) {
return token
}
// Access token has expired, try to update it
return refreshAccessToken(token)
},
async session(session, token) {
session.accessToken = token.accessToken
return session
}
},
events: {
async signIn(message) { console.log('success signin') },
async signOut(message) { console.log('success signout') },
async createUser(message) { console.log('success user create') },
async updateUser(message) { console.log('success update user') },
async session(message) { console.log('success session') },
async error(message) { console.log('error') }
},
// A database is optional, but required to persist accounts in a database
database: `mongodb+srv://${process.env.NOSQL_USER}:${process.env.NOSQL_PWD}#${process.env.NOSQL_HOST}/${process.env.NOSQL_TABLE}`,
});
I’m still a beginner on NextJS and React in particular:) Thanks for your help

How to use include "users" in restangular login?

I want to store token and user information in local storage ,things like store token and userId are okay except I can't include users detail information like email
this.login = function (data) {
var loginResults = Restangular.one('/users/login')
.post(undefined, data)
.then(function (data) {
var mytoken = data.id;
storeToken(data);
Restangular.setDefaultHeaders({ accept: 'application/json', access_token: mytoken });
},
function (Response) {
console.log("There was an error.");
});
return loginResults;
}
Finally I got the correct answer to include "user" here is the result....
this.login = function (data) {
var loginResults = Restangular.one('/persons/login')
.post(undefined, data, {
include: "user"
})
.then(function (data) {
var mytoken = data.id;
storeToken(data);
Restangular.setDefaultHeaders({ accept: 'application/json', access_token: mytoken });
$state.go('home');
}, function (Response) {
console.log("There was an error.");
alert("Login Failed");
});
return loginResults;
}