I return the following JSON after confirming credentials:
{username: 'foo', name: 'bar', type: 123}
However, NextAuth does not allow me to store all the fields due to model limitations, so what it returns in JWT to client is:
{name: 'bar', email: null, image: null}
My [...nextauth].js setup is very basic:
providers: [
Providers.Credentials({
async authorize(credentials) {
const res = await fetch('http://localhost:3000/api/user', {
method: 'GET',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'credentials': JSON.stringify(credentials)
}
})
const user = await res.json()
if (user && !user.message) {
return user
} else {
return null
}
}
})
],
The only solution I came up with is to fake email field with JSON string in which I can store everything I need:
{name: 'bar', email: "{username: 'foo', type: 123}", image: null}
How can I do it properly? I tried looking into custom models (https://next-auth.js.org/tutorials/typeorm-custom-models), but it seems to be only about databases, which is not my case since I use JWT for session storage.
Also what drawbacks I can encounter if I continue with my solution?
You will need to persist the additional info through callbacks, at first through JWT's callback and then Session's callback:
callbacks: {
async jwt(token, user, account, profile, isNewUser) {
// Since you are using Credentials' provider, the data you're persisting
// _should_ reside in the user here (as far as can I see, since I've just tested it out).
// This gets called whenever a JSON Web Token is created (once) or updated
if (user?.type) {
token.status = user.type
}
if (user?.username) {
token.username = user.username;
}
return token
},
async session(session, token) {
session.type = token.type;
session.username = token.username;
return session
}
}
Related
I use fabric Kony and I have given to Postman Username pass of Fabric to authenticate
enter image description here
and entered this prerequest script:
const postRequest = {
url: 'https://sandbox-api.marqeta.com/v3/swagger.json',
method: 'POST',
timeout: 0,
header: {
"Content-Type": "application/x-www-form-urlencoded"
},
body: {
mode: 'urlencoded',
urlencoded: [
{key: "grant_type", value: "password"},
{key:"username", value: "........."},
{key:"password", value: ".........."},
]}
};
pm.sendRequest(postRequest, function (err, res) {
var responseJson = res.json();
console.log(responseJson);
pm.environment.set('ACCESS_TOKEN', responseJson['access_token']);
});
I'm not an user of POSTMAN, but I know a little of Kony Fabric.
If you hit the web url of a Kony Fabric you'll notice that the first call will generate an oauth_token (for example 0526b30c-6579-4965-a774-87224815ea3a) that will be used for further calls.
I think that you should catch this token before trying to connect to the Kony Fabric with a user's credentials.
Cordially,
Hervé N.
I am having issues with sending files to the endpoint: https://developer.api.autodesk.com/photo-to-3d/v1/file
Once I receive the Auth token, I successfully create a Photo Scene with: https://developer.api.autodesk.com/photo-to-3d/v1/photoscene.
Then I also check, if the Photo scene is indeed created by calling the: https://developer.api.autodesk.com/photo-to-3d/v1/photoscene/${photosceneid}/properties.
If that goes through, I send the image files, which I first upload to a storage server
(because sending the files directly didnt work) and then I run:
let image_urls = await temporary_image_upload(files, photosceneid)
const form_data = new FormData();
form_data.append("photosceneid", photosceneid)
form_data.append("type", "image")
image_urls.forEach(url => form_data.append("file", url))
// I also tried:
// image_urls.forEach((url, index) => form_data.append(`file[${index}]`, url))
// Upload photos
const { data } = await axios.post(
"https://developer.api.autodesk.com/photo-to-3d/v1/file",
form_data,
{ headers }
)
//
//
// I also tried adding it as query params:
image_urls = image_urls.map((url, index) => `file[${index}]=${url}`).join("&")
// Upload photos
const { data } = await axios.post(
"https://developer.api.autodesk.com/photo-to-3d/v1/file",
`photosceneid=${photosceneid}&type=image&${image_urls}`,
{ headers }
)
But nothing seems to work and I get response:
{
Usage: '0.47925591468811',
Resource: '/file',
Error: {
code: '19',
msg: "Specified Photoscene ID doesn't exist in the database"
}
}
So I am not sure what might be wrong, since I can clearly verify that the Photo Scene has been created.
Could you please provide some support, been struggling with this for a few days now.
As you mentioned you can clearly confirm the photosceneid exists, I would suspect that your axios request is not as expected, maybe add details about your header. Here is a sample:
Axios({
method: 'POST',
url: 'https://developer.api.autodesk.com/photo-to-3d/v1/file',
headers: {
'content-type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + access_token
},
data: querystring.stringify({
photosceneid: photosceneId,
type: 'image',
'file[0]': 'https://path/to/file.JPG'
})
})
I am able to call the API ,I have set the params with id having key and values which needs to be pass dynamically as received from the server (ex:s1,s3,s4..these are sensor names received from the server) and I have to pass these sensor names dynamically .
.service.ts
export class DashboardService {
public sensors: any[];
constructor(private http: HttpClient, private router: Router) {
}
sensorstart(tokenstr) {
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
'Authorization': 'Token ' + tokenstr
}),
params: new HttpParams().set('id', JSON.stringify(this.sensors.map(itm => itm.name)))
};
this.http.get(environment.apiUrl + '/api/sensors/start?' + this.id, httpOptions).subscribe(
(senst: any[]) => {
// localStorage.setItem("senst",JSON.stringify(senst));
console.log('senst:', JSON.parse(localStorage.getItem('senst')));
this.router.navigate(['/dashboard']);
},
err => {
console.log('Error', err);
}
);
}
}
.component.ts
this.jammerstart();
--some code--
sensorstart(){
this.senst=JSON.parse(localStorage.getItem("senst"));
console.log("senst",this.senst)
}
But in console It is showing
{
"status": true,
"action": "sensor started"
}
But I want to show the sensor name in action what I have called dynamically in calling the API.
I want the below result which changes dynamically in console
{
"status": true,
"action": "sensor j3 started"
}
How can I Pass the id values (sensor names s1,s2,s3--)dynamically in calling the API.
The question seems to be how pass an dynamic array (like s1,s2,s3) to the server.
This is actually depending how the server API has been designed.
If you build the HttpParams like you did:
const sensors: any[] = [{name: 's1'},{name: 's2'},{name: 's3'}];
const httpOptions = {
params: new HttpParams().set('id', JSON.stringify(sensors.map(itm => itm.name)))
};
this.httpClient.get('api/sensors/start', httpOptions).subscribe();
The request url will be something like this:
/api/sensors/start?id=%5B%22s1%22,%22s2%22,%22s3%22%5D
Which is the encoded string for ["s1","s2","s3"]
If you want to send it like this
/api/sensors/start?id=s1&id=s2&id=s3
You may have to do this:
const sensors: any[] = [{name: 's1'},{name: 's2'},{name: 's3'}];
let httpParams = new HttpParams();
for (const sensor of sensors) {
httpParams = httpParams.append('id', sensor.name);
}
const httpOptions = {
params: httpParams
};
this.httpClient.get('api/sensors/start', httpOptions ).subscribe();
You have to adapt the way you are sending your array depending what the server side is accepting.
The server could also accept another shape:
/api/sensors/start?id[]=s1&id[]=s2&id[]=s3
or
/api/sensors/start?id%5B%5D=s1&id%5B%5D=s2&id%5B%5D=s3
or
/api/sensors/start?id=s1,s2,s3
https://medium.com/raml-api/arrays-in-query-params-33189628fa68
I'm getting APN Invalid parameter: JSON must contain an entry for 'default' or 'APNS_SANDBOX'. the log is here
And the code block is here:
how to fix this? this is built in scala lift framework.
This is the example in javascript. In the same way, we have to use. Need to use cases for
1.APNS_SANDBOX
2.APNS
3.default
// Setup SNS Client
const snsClient = new SNS();
// whatever your full endpoint arn is. (from createPlatformEndpoint)
const endpointArn = 'arn:aws:sns:...';
// any extra data you want passed along with the message
const payload = {
someCustomKey: 'someCustomValue'
};
// send it
snsClient.publish({
TargetArn: endpointArn,
MessageStructure: 'json', // so we can put in a custom payload and message
Message: JSON.stringify({
default: `DEFAULT MESSAGE ${message}`,
APNS_SANDBOX: JSON.stringify({
aps: {
alert: `IOS Sandbox SPECIFIC MESSAGE ${message}`,
},
payload,
}),
APNS: JSON.stringify({
aps: {
alert: `IOS Prod SPECIFIC MESSAGE ${message}`,
},
payload,
}),
}),
}).promise().then(() => {
console.log('Notification sent!');
}).catch((err) => {
console.log('Failed to send with:', err);
});
Used this link for reference
I want to call an Apify actor and specify a parameter value via a call to the Apify API.
The actor is the Google Search Results Scraper located here.
Here is where the docs say to use queries as the object property name in the API call payload.
The following table shows specification of the actor INPUT fields as defined by its input schema. These fields can be [...] provided in a JSON object when running the actor using the API. Read more in docs.
...
Search queries or URLs
Google Search queries (e.g. food in NYC) and/or full URLs (e.g. https://www.google.com/search?q=food+NYC).
Enter one item per line.
Optional
Type: String
JSON example
"queries": "Hotels in NYC
Restaurants in NYC
https://www.google.com/search?q=restaurants+in+NYC"
After I run my Google Apps Script code, I expect to see a change in the searchQueries.term parameter to be the following.
Apify — what I expect to see
"searchQuery": {
"term": "Banks in Phoenix", // what I am trying to change to by API call
// [...]
},
But what I actually get is the same parameter value as existed the last time I ran the actor manually. As follows.
Apify — what I actually see
"searchQuery": {
"term": "CPA firms in Newark", // remaining from last time I ran the actor manually
// [...]
},
Here is the code I'm running from Google Apps Script.
Code.gs
const runSearch = () => {
const apiEndpoint= `https://api.apify.com/v2/actor-tasks/<MY-TASK-NAME>/run-sync?token=<MY-TOKEN>`
const formData = {
method: 'post',
queries: 'Banks in Phoenix',
};
const options = {
body: formData,
headers: {
'Content-Type': 'application/json',
},
};
UrlFetchApp.fetch(apiEndpoint, options,);
}
What am I doing wrong?
You are missing the payload property in the request object.
Change:
queries: 'Banks in Phoenix',
to:
payload: {
queries: 'Banks in Phoenix',
}
Code.gs
const runSearch = () => {
const apiEndpoint= `https://api.apify.com/v2/actor-tasks/<MY-TASK-NAME>/run-sync?token=<MY-TOKEN>`
const formData = {
method: 'post',
payload: {
queries: 'Banks in Phoenix',
},
};
const options = {
body: formData,
headers: {
'Content-Type': 'application/json',
},
};
UrlFetchApp.fetch(apiEndpoint, options,);
}