How to return two variables from ClientRequest? - http

I made http request (Class: ClientRequest) and I need to return two variables from my "login method" via promise.
function login(name, pass,server) {
return new Promise((resolve, reject) => {
const request = net.request({
method: 'GET',
url: server+'/names.nsf?Login&Username=' + name + '&Password=' + pass,
useSessionCookies: true,
redirect: 'follow'
}
)
var first
var second
///first
request.on('response', (response) => {
...
first = response.statusCode
})
///second
request.on('redirect', (statusCode, method, redirectUrl) => {
...
second = redirectUrl
})
resolve([first, second])
request.end()
});
}
And I am using it in this way:
ipcMain.on('loginbackend', async (event, arg) => {
try {
const loginInfo = await login(arg.name, arg.pass,arg.server)
event.returnValue = loginInfo
}
catch (error) {
console.error('ERROR:');
console.error(error);
}
});
I can return var putting resolve() into request.on method, but I need return both vars from both request.on. It seems request.on is asynchronize, how can I do that?

You should return your variables when end event of response is emited
function login(name, pass, server) {
return new Promise((resolve, reject) => {
const request = net.request({
method: 'GET',
url: server + '/names.nsf?Login&Username=' + name + '&Password=' + pass,
useSessionCookies: true,
redirect: 'follow'
}
)
var first
var second
///first
request.on('response', (response) => {
...
first = response.statusCode
response.on('end', () => {
resolve([first, second]);
});
})
///second
request.on('redirect', (statusCode, method, redirectUrl) => {
...
second = redirectUrl
})
request.end()
});
}

Related

Why HttpContext.Session.GetString returns null?

This is my session save and fetch method:
[HttpPost]
[Route("save-to-session")]
public IActionResult SaveToSession(string id)
{
HttpContext.Session.SetString("user", id);
return Content(id);
}
[HttpGet]
[Route("fetch-from-session")]
public IActionResult FetchFromSession()
{
string name = HttpContext.Session.GetString("user");
return Content(name);
}
I'm using Sql Server Cache:
services.AddDistributedSqlServerCache(options => {
options.ConnectionString = Configuration.GetConnectionString("TestMEApiContext");
options.SchemaName = "dbo";
options.TableName = "Session";
});
services.AddSession(options => {
options.Cookie.Name = ".Session";
options.IdleTimeout = TimeSpan.FromMinutes(3000);
options.Cookie.HttpOnly = true;
options.Cookie.IsEssential = true;
});
and the data is saved to the database but when i try to fetch it always returns null.
This is how i try to fetch it in my react code:
fetch(`https://localhost:44369/api/users/fetch-from-session`, { method: 'GET', credentials: 'include', mode: 'cors' }).then(function (body) {
return body.text();
}).then((response) => {
console.log("My response")
console.log(response) // <-THIS IS NULL
});
And this is how i try to save it but save works:
await this.getUserId().then(async function (userId) {
fetch(`https://localhost:44369/api/users/save-to-session?id=${userId}`, {
method: 'POST',
mode: 'cors',
credentials: 'include'
});
})

Microsoft Teams Tab with MSAL sign in

I've been working on getting a custom tab working in MS teams using MSAL. I've been following the example here: https://github.com/nmetulev/teams-msal and I can generate a token. I then try to forward this token to my API, where I build a security claim and call SignInAsync() to persist the cookie.
This then gets stored, and I forward to my standard page, but this does not page auth (I get unauthorized). Is there something I'm missing that I need to be doing?
Auth Page
const signIn = () => {
msalApp.acquireTokenRedirect(authenticationParameters);
}
const handleSignedIn = () => {
microsoftTeams.initialize();
microsoftTeams.authentication.notifySuccess();
}
const handleSignedOut = (error) => {
microsoftTeams.initialize();
microsoftTeams.authentication.notifyFailure(error);
}
const handleErrorReceived = (authError, accountState) => {
console.log(authError, accountState);
handleSignedOut({authError});
}
const handleTokenReceived = (response) => {
console.log(response);
handleSignedIn();
}
// MAIN
const msalApp = new Msal.UserAgentApplication(msalConfig);
msalApp.handleRedirectCallback((response) => handleTokenReceived(response), (error, state) => handleErrorReceived(error, state));
microsoftTeams.initialize();
microsoftTeams.getContext((context) => {
authenticationParameters = {
scopes: scopes,
loginHint: context.loginHint
};
setTimeout(() => {
attemptSilentSignIn().then(success => {
if (success) {
handleSignedIn();
} else {
signIn();
}
});
},
4000);
});
Sign In Page:
const attemptSilentSignIn = () => {
renderLoading();
if (msalApp.getAccount()) {
msalApp.acquireTokenSilent({ scopes }).then((response) => {
if (response && response.accessToken) {
handleSignedIn(response.accessToken);
} else {
handleSignedOut();
}
}, () => {
handleSignedOut();
})
} else {
handleSignedOut();
}
}
const signIn = () => {
renderLoading();
microsoftTeams.initialize(() => {
microsoftTeams.authentication.authenticate({
url: window.location.origin + "/resources/TeamsAuthFlow.html",
successCallback: () => attemptSilentSignIn(),
failureCallback: (error) => renderError(error)
});
});
}
const handleSignedIn = (accessToken) => {
microsoftTeams.initialize();
microsoftTeams.getContext((context) => {
var tenant = $("<input>").attr("id", "TenantId").attr("name", "TenantId").val(context.tid);
var token = $("<input>").attr("id", "AuthToken").attr("name", "AuthToken").val(accessToken);
var form = $("<form>").css("display", "none").attr("id", "target").attr("method", "POST").attr("action", "/api/TeamsTabSignIn").append(tenant).append(token).submit();
$("body").append(form);
$("#target").submit();
});
}
const handleSignedOut = () => {
renderSignedOutView();
}
// MAIN
let app = document.querySelector('.app');
const msalApp = new Msal.UserAgentApplication(msalConfig);
attemptSilentSignIn();
let authenticationParameters = null;
const handleErrorReceived = (authError, accountState) => {
console.log(authError, accountState);
handleSignedOut({ authError });
}
const handleTokenReceived = (response) => {
console.log(response);
handleSignedIn();
}
API Call
TenantId = Context.Request.Form["TenantId"];
AuthToken = Context.Request.Form["AuthToken"];
var principal = await _authHelper.SetPlatformUser(TenantId, AuthToken);
if (principal is ClaimsPrincipal cp)
{
await Context.SignInAsync("Cookies", cp, new AuthenticationProperties { IsPersistent = true });
Response.Redirect("/app/teamspage/Ticket");
}

#typescript-eslint/no-misused-promises and new Promise(() => return resolve())

I have a Promise(() => return resolve()) pattern in a function I got from firebase functions samples.
const appendPromise = (requestWithoutAuth: {
spreadsheetId: any
range: string
valueInputOption: string
insertDataOption: string
resource: { values: any[][] }
}): Promise<any> => {
// eslint-disable-next-line #typescript-eslint/no-misused-promises
return new Promise((resolve, reject) => {
return getAuthorizedClient().then((client) => {
const sheets = google.sheets('v4')
const request = requestWithoutAuth
request.auth = client
return sheets.spreadsheets.values.append(request, (err: any, response: { data: unknown }) => {
if (err) {
console.log(`The API returned an error: ${err}`)
return reject(err)
}
return resolve(response.data)
})
})
})
}
eslint complains about #typescript-eslint/no-misused-promises.
I'm not used to that, is it enough to replace new Promise() by Promise.resolve() ?
Thanks
I believe the linter's problem is that you use a Promise inside a Promise constructor. Use an async function and move the Promise constructor one indentation lower:
const appendPromise = async (requestWithoutAuth: {
spreadsheetId: any
range: string
valueInputOption: string
insertDataOption: string
resource: { values: any[][] }
}): Promise<any> => {
const client = await getAuthorizedClient();
return new Promise((resolve, reject) => {
const sheets = google.sheets('v4')
const request = requestWithoutAuth
request.auth = client
return sheets.spreadsheets.values.append(request, (err: any, response: { data: unknown }) => {
if (err) {
console.log(`The API returned an error: ${err}`)
return reject(err)
}
return resolve(response.data)
})
})
}

How do I access the return of an axios function? Or should I be using callback?

Getting some records and making a POST command to send off, am able to see the correct record Id's in the log so the logic works. Just don't know how to retrieve the values, I have tried async/await and get an unresolved promise response and running as is comes back undefined. New to async, any help is greatly appreciated!
const axios = require('axios');
exports.handler = (event, context, callback) => {
async function getJobId() {
var jobId
axios({
method: 'get',
headers: {'<Api-Key>': '<my-api-key-value>'},
url: 'https://api.my-website.com/v1/jobs',
params: { jobNumber: event.jobNumber }
})
.then((res) => {
var i,j,x;
for (i in res.data) {
for (j in res.data[i]){
x = res.data[i][j];
jobId = x.id;
}
}
console.log('jobId:',jobId);
return jobId;
})
.catch(function (error) {
console.log('getJobIdError');
console.log(error);
});
}
function getMaterialId() {
var materialId;
axios({
method: 'get',
headers: {'<Api-Key>': '<my-api-key-value>'},
url: 'https://api.my-website.com/v1/materials',
})
.then((res) => {
var i,j,x;
for (i in res.data) {
for (j in res.data[i]){
x = res.data[i][j];
if(x.primaryVendor.vendorPart == event.material){
materialId = x.id;
}
}
}
console.log('materialId:',materialId);
return materialId;
})
.catch(function (error) {
console.log('getMaterialIdError');
console.log(error);
});
}
function getTechId() {
var techId;
axios({
method: 'get',
headers: {'<Api-Key>': '<my-api-key-value>'},
url: 'https://api.my-website.com/v1/technicians',
})
.then((res) => {
var i,j,x;
var fn = event.firstName;
var ln = event.lastName;
var fullName = fn.trim() + ' ' + ln.trim();
for (i in res.data) {
for (j in res.data[i]){
x = res.data[i][j];
if(x.name == fullName){
techId = x.id;
}
}
}
console.log('techId:', techId);
return techId;
})
.catch(function (error) {
console.log('getTechId');
console.log(error);
});
}
function allIds() {
axios.all([
getMaterialId(),
getJobId(),
getTechId()
]);
}
allIds();
};
In the output log I get the correct record Id's:
Response:
null
Request ID: "50972993-4971-4dcc-b577-0f253f3f3571"
Function Logs:
START RequestId: 50972993-4971-4dcc-b577-0f253f3f3571 Version: $LATEST
2019-08-17T21:51:51.192Z 50972993-4971-4dcc-b577-0f253f3f3571 techId: 1025
2019-08-17T21:51:51.233Z 50972993-4971-4dcc-b577-0f253f3f3571 materialId: 1725
2019-08-17T21:51:51.432Z 50972993-4971-4dcc-b577-0f253f3f3571 jobId: 37399080
END RequestId: 50972993-4971-4dcc-b577-0f253f3f3571
REPORT RequestId: 50972993-4971-4dcc-b577-0f253f3f3571 Duration: 1148.69 ms Billed Duration: 1200 ms Memory Size: 128 MB Max Memory Used: 65 MB
I got it, Rohit Kashyap pointed me in the right direction, thank you Rohit. I was trying to avoid the nested axios as I read that can get sticky but seems to work pretty well here. It does what I need but am new to async so please let me know if anyone sees an issue.
const axios = require('axios');
exports.handler = (event, context, callback) => {
var jobId;
var materialId;
var techId;
axios.all([
axios({
method: 'get',
headers: {'<Api-Key>': '<my-api-key>5'},
url: 'https://api.my-website.com/v1/jobs',
params: { jobNumber: event.jobNumber }
})
.then((res) => {
var i,j,x;
for (i in res.data) {
for (j in res.data[i]){
x = res.data[i][j];
jobId = x.id;
}
}
console.log('jobId:',jobId);
})
.catch(function (error) {
console.log('getJobIdError');
console.log(error);
}),
axios({
method: 'get',
headers: {'<Api-Key>': '<my-api-key>5'},
url: 'https://api.my-website.com/v1/materials',
})
.then((res) => {
var i,j,x;
for (i in res.data) {
for (j in res.data[i]){
x = res.data[i][j];
if(x.primaryVendor.vendorPart == event.material){
materialId = x.id;
}
}
}
console.log('materialId:',materialId);
})
.catch(function (error) {
console.log('getMaterialIdError');
console.log(error);
}),
axios({
method: 'get',
headers: {'<Api-Key>': '<my-api-key>5'},
url: 'https://api.my-website.com/v1/technicians',
})
.then((res) => {
var i,j,x;
var fn = event.firstName;
var ln = event.lastName;
var fullName = fn.trim() + ' ' + ln.trim();
for (i in res.data) {
for (j in res.data[i]){
x = res.data[i][j];
if(x.name == fullName){
techId = x.id;
}
}
}
console.log('techId:', techId);
})
.catch(function (error) {
console.log('getTechIdError');
console.log(error);
})
])
.then((res) => {
callback( null, {
jobId,
materialId,
techId,
});
})
.catch(function (error) {
console.log('getAllIdError');
console.log(error);
});
};

Observable from 2 promises

I think my solution is in this question but I can't get it to work Promise.all behavior with RxJS Observables?
I'm trying to return an observable on two promises via forkJoin.
One promise gets an ID from the server and another processes a file to generate a thumbnail.
export function createSceneFromFile(action$) {
return action$.ofType(CREATE_SCENE_FROM_FILE)
.mergeMap(({locationId,file}) =>
createSceneThumb(locationId,file)
.map((res,preview) => {
console.log(res,preview)
if (res.error) {
return { type: CREATE_SCENE_FAILED, payload: res.message }
} else {
return {type: CREATE_SCENE_SUCCESS, payload: {...res.payload,preview} }
}
})
.catch(err => { return { type: CREATE_SCENE_FAILED, message: err } })
)
}
function createSceneThumb(locationId,file){
const request = fetch(`${API_URL}/location/${locationId}/createscene/${file.name}/`, {
method: 'get',
credentials: 'include',
}).then(res => res.json())
const thumb = fileToScenePreview(file)
return Observable.forkJoin(request,thumb)
}
export function fileToScenePreview(file){
return new Promise((resolve,reject)=>{
getFileThumb(file).then((canvas)=> {
canvas.toBlob((blob) => {
blob.lastModifiedDate = new Date()
blob.name = 'scenepreview_' + file.name + '.png'
const uploader = new S3Upload({
getSignedUrl: getSignedUrl,
uploadRequestHeaders: {'x-amz-acl': 'public-read'},
contentType: 'image/png',
scrubFilename: (filename) => filename.replace(/[^\w\d_\-.]+/ig, ''),
contentDisposition: 'auto',
s3path: 'assets/',
onError:()=>reject,
onFinishS3Put: ()=>resolve(blob.name),
})
uploader.uploadFile(blob)
})
})
})
}
But i never get a response.
Is this the right way of going about it?

Resources