const { paymentId } = req.body;
const refundURI = `https://api.sandbox.paypal.com/v2/payments/captures/${paymentId}/refund`;
// get access token
const { access_token } = await generateToken();
// console.log(JSON.stringify(access_token));
const refundObj = await Axios.post(refundURI, {
headers: {
Accept: `application/json`,
Authorization: `Bearer ${access_token}`,
},
body: JSON.stringify({
amount: {
currency_code: "USD",
value: "10.00",
},
}),
});
I am trying to refund a paypal payment .I am generating access token but still its giving unAuthorized with 401 status code .
Related
I get this to work locally, but get a Response Error: Unauthorized on Vercel.
I've created a Single Sender Verification on Sendgrid which is verified.
I've tried creating a new API key on Sendgrid but it still dosen't work.
I'm out of options.
This is my code in the api route:
import type { NextApiRequest, NextApiResponse } from "next";
const sgMail = require("#sendgrid/mail");
type EmailData = {
to: string;
from: string;
subject: string;
text: string;
html: string;
};
type DataResponse = {
data?: any;
success: boolean;
error?: string;
};
const emailAddress = process.env.SENDGRID_EMAIL as string;
const emailAddressTo = process.env.SENDGRID_EMAIL_TO as string;
sgMail.setApiKey(process.env.SENDGRID_API_KEY as string);
export default async function _(req: NextApiRequest, res: NextApiResponse<DataResponse>) {
if (req.method !== "POST") {
res.status(400).json({ success: false, error: "Invalid request" });
return;
}
const data = JSON.parse(req.body);
const { name, email, phone = "", message = "" } = data;
console.log("sgMail", sgMail);
console.log("--------------");
console.log("process.env.SENDGRID_API_KEY", process.env.SENDGRID_API_KEY);
console.log("--------------");
console.log("SENDGRID_EMAIL", process.env.SENDGRID_EMAIL);
console.log("--------------");
console.log("SENDGRID_EMAIL_TO", process.env.SENDGRID_EMAIL_TO);
console.log("--------------");
const text = `
Name: ${name} \r\n
Email: ${email} \r\n
Phone: ${phone} \r\n
message: ${message} \r\n
`;
let emailData: EmailData = {
to: emailAddressTo,
from: emailAddress,
subject: "Form submission",
text: text,
html: `<div>${text.replace(/\r\n/g, "<br>")}</div>`,
};
try {
await sgMail.send(emailData);
} catch (error) {
console.log(error);
res.status(400).json({ success: false, error: "Error while sending email" });
return;
}
res.status(200).json({ success: true, data: {} });
}
This is the log from the server with the error messages:
sgMail MailService {
client: Client {
auth: 'Bearer HIDDEN BUT ITS THERE',
impersonateSubuser: '',
defaultHeaders: {
Accept: 'application/json',
'Content-Type': 'application/json',
'User-Agent': 'sendgrid/7.7.0;nodejs'
},
defaultRequest: {
baseUrl: 'https://api.sendgrid.com/',
url: '',
method: 'GET',
headers: {},
maxContentLength: Infinity,
maxBodyLength: Infinity
}
},
substitutionWrappers: [ '{{', '}}' ],
secretRules: [],
MailService: [class MailService]
}
--------------
process.env.SENDGRID_API_KEY HIDDEN BUT ITS THERE
--------------
SENDGRID_EMAIL HIDDEN BUT ITS THERE
--------------
SENDGRID_EMAIL_TO: HIDDEN BUT ITS THERE
--------------
ResponseError: Unauthorized
at node_modules/#sendgrid/client/src/classes/client.js:146:29
at processTicksAndRejections (node:internal/process/task_queues:96:5) {
code: 401,
response: {
headers: {
server: 'nginx',
date: 'Sun, 19 Feb 2023 20:57:56 GMT',
'content-type': 'application/json',
'content-length': '97',
connection: 'close',
'access-control-allow-origin': 'https://sendgrid.api-docs.io',
'access-control-allow-methods': 'POST',
'access-control-allow-headers': 'Authorization, Content-Type, On-behalf-of, x-sg-elas-acl',
'access-control-max-age': '600',
'x-no-cors-reason': 'https://sendgrid.com/docs/Classroom/Basics/API/cors.html',
'strict-transport-security': 'max-age=600; includeSubDomains'
},
body: { errors: [Array] }
}
}
Vercel deployments use dynamic IP addresses due to the dynamic nature of the platform and in Sendgrid their IP Access management was on, which meant that all requests from Vercel were blocked..
SOLUTION:
You can disable IP Access Management to reopen account access to any IP address and no longer maintain a list of allowed addresses.
From the Settings > IP Access Management page, click Disable Allow List.
A dialog will open asking you to confirm the decision. Click Disable.
I have a problem. When I send a login request to the server, I get a status code of 200, but no token in response. Can you tell me what the problem is
import { createApi, fetchBaseQuery } from "#reduxjs/toolkit/query/react";
import { setCredentials, logOut } from "../services/features/authSlice";
const baseQuery = fetchBaseQuery({
baseUrl: "https://central-park.doniraj-krv.w3lab.cloud",
mode: "no-cors",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
},
prepareHeaders: (headers, { getState }) => {
const token = getState().auth.token;
console.log(token);
if (token) {
headers.set("Authorization", `Bearer ${token}`);
}
// headers.set("Accept", "application/json");
// headers.set("Content-Type", "application/json");
return headers;
},
});
const baseQueryWithReauth = async (args, api, extraOptions) => {
let result = await baseQuery(args, api, extraOptions);
if (result?.error?.originalStatus === 403) {
console.log("sending refresh token");
// send refresh token to get new access token
const refreshResult = await baseQuery(
"/api/auth/refresh",
api,
extraOptions
);
console.log(refreshResult);
if (refreshResult?.data) {
const user = api.getState().auth.user;
// store the new token
api.dispatch(setCredentials({ ...refreshResult.data, user }));
// retry the original query with new access token
result = await baseQuery(args, api, extraOptions);
} else {
api.dispatch(logOut());
}
}
return result;
};
export const apiSlice = createApi({
reducerPath: "api",
baseQuery: baseQueryWithReauth,
endpoints: (builder) => ({}),
});
When I send POST request, I have status code 200 but response is empty
I am using Next.js and Next Auth to talk to my backend C# ASP.NET API.
My API's response is the following DTO:
{
"data": {
"accessToken": "string",
"refreshToken": "string",
"email": "user#example.com",
"username": "string",
"roles": [
"string"
]
},
"success": true,
"message": "string"
}
I am having a hard time getting that info into the next auth session so that I can grab it with useSession().
I'd also like to be able to display the API "message" to the user in the login form. Incase their account is locked or whatever.
This is what I have:
[...nextauth].js
import NextAuth from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials";
import { API_URL } from "#/constants";
export const authOptions = {
// Configure one or more authentication providers
providers: [
// Add Your Providers Here
CredentialsProvider({
name: "Credentials",
credentials: {
username: { label: "Username", type: "text", placeholder: "jsmith" },
password: { label: "Password", type: "password" },
},
async authorize(credentials, req) {
const { usernme, password } = credentials;
const body = JSON.stringify({
username,
password,
});
// Login request to our API.
const res = await fetch(`${API_URL}/Login`, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json; charset=utf-8",
},
body: body,
});
const data = await res.json();
// Our API's response contains
/*
{
"data": {
"accessToken": "string",
"refreshToken": "string",
"email": "user#example.com",
"username": "string",
"roles": [
"string"
]
},
"success": true,
"message": "string"
}
*/
const user = {
success: data.success,
message: data.message,
email: data.data.email,
username: data.data.username,
accessToken: data.data.accessToken,
refreshToken: data.data.refreshToken,
roles: data.data.roles,
};
// EVERYTHING TO HERE IS GOOD!
// I CAN GET THE user OBJECT FILLED.
if (res.ok && user) {
return user; //<---- is this actually returning the full user object to the session?
} else {
return null;
}
},
}),
],
pages: { signIn: "/login" },
};
export default NextAuth(authOptions);
Navbar Links:
<Nav.Link as={Link} href='/login' onClick={() => signIn()}>Login</Nav.Link>
<Nav.Link as={Link} href='/signout' onClick={() => signOut({callbackUrl: '/'})}>Signout</Nav.Link>
Login form:
// Get data from the form.
const nextAuthSettings = {
username: event.target.username.value,
password: event.target.password.value,
redirect: true,
callbackUrl: "/dashboard",
};
// Send the form data to Next Auth
const result = await signIn("credentials", nextAuthSettings);
// Error Handling
// THIS DOES NOT WORK
// I don't think signIn() returns a copy of the user object unfortunately...
if (!result.success) {
// Display the API Error Message On The Page
setErrorMsg(result.message);
}
And then in various pages, when I want to access the user object I am doing this :
import { useSession } from "next-auth/react";
const { data: session } = useSession();
// This only shows the email
<span>{session?.user.email}</span>;
// It looks like a JWT or something when I console log it
{
"user": {
"email": "users#email.com"
},
"expires": "2023-03-16T12:39:28.120Z"
}
Any help appreciated!
I need to be able to access the user object my API is returning throughout my app.
At the moment I'm just getting this session.user.email and nothing else ??
it's like I am not mapping the API's response to whatever Next Auth wants me to create...
you have to use callbacks :
callbacks: {
async jwt({ user, token }) {
// update token from user
if (user) {
token.user = user;
}
// return final_token
return token;
},
async session({ session, token }) {
// update session from token
session.user = token.user;
return session;
},
},
Now you can access your session with useSession() and your token with getToken()
I'm using the JWT Authentication for WP-API plugin to generate the token.
User crendetials are submitted to /jwt-auth/v1/token endpoint then store token to cookie then setState as follow
setAuth({ status: 'SIGNED_IN', user: response.data.user_display_name});
then on restricted page I check if user is valid from getServerSideProps
export const authenticateUser = async (ctx) => {
try {
const response = await axios.get(`${process.env.NEXT_PUBLIC_API_URL}/wp/v2/users/me`, {}, {
headers: {
'Authorization': `Bearer ${token}`
}
});
// if is it returns the right informations
return { status: 'SIGNED_IN', user: response.data.user}
// else
return { status: 'SIGNED_OUT', user: null}
}
}
export const getServerSideProps = async context => {
// retrieve user
const auth = await authenticateUser(context);
console.log(auth);
// if there is no authenticated user, redirect to homepage
if (auth.status === 'SIGNED_OUT') {
return {
props: {},
redirect: { destination: "/" },
}
}
return { props: { user: auth.user } }
}
In postman the requests are working fine using the right authorization bearer token.
But in my nextjs app I have the following response
{
code: 'rest_not_logged_in',
message: 'Vous n’êtes actuellement pas connecté.',
data: { status: 401 }
}
I also tried to check if user id exists using
const response = await axios.get(`${process.env.NEXT_PUBLIC_API_URL}/wp/v2/users/${userId}`, {}, {
headers: {
'Authorization': `Bearer ${token}`
}
});
but I have the following response
{
code: 'rest_user_cannot_view',
message: 'Désolé, vous n’avez pas l’autorisation de lister les comptes.',
data: { status: 401 }
}
Any help will be appreciate.
EDIT
It appears that the problem come from axios, fetch API works great.
I am trying to sign up users on Firebase Auth using Google Apps Script via the Firebase Auth REST API.
My code looks this.
var apiKey = "XXXX";
var url = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/signupNewUser?key=" + apiKey;
var options = {
method: 'post',
contentType: 'application/json',
email: "email#gmail.com",
password: "12345678",
returnSecureToken: true
};
var response = UrlFetchApp.fetch(url, options);
I am receving the following error.
{
"error": {
"code": 400,
"message": "ADMIN_ONLY_OPERATION",
"errors": [
{
"message": "ADMIN_ONLY_OPERATION",
"domain": "global",
"reason": "invalid"
}
]
}
}
How do I go about this?
Request body payload should be sent as a 'payload' property of the options object.
var payload = {
email: "sauravo14#gmail.com",
password: 12345678,
returnSecureToken: true
};
var options = {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload)
};