I'm trying to use a custom serializer but it doesn't seem to work for me, my serializer is never called. What am I doing wrong?
I create a logger like this:
const mask = token => {
console.log({token})
return typeof token === 'string' ? token.replace(/[^\.]+$/, 'REDACTED') : token
}
const log = context.log = createLogger({
name: '_placeholder',
level: process.env.LOG_LEVEL || 'info',
serializers: {authorization: mask, bearer: mask, Authorization: mask}
})
and then I log like this:
console.log({properties})
log[!status ? 'error' : status < 500 ? 'info' : 'warn']({error: merge({message, ...properties}, status && {status})})
Output piped to bunyan:
{ properties:
{ reason: 'InvalidToken', authorization: 'Bearer foo.bar.baz' } }
[2018-08-14T14:37:11.775Z] INFO: _placeholder/9920 on XXX:
error: {
"message": "Invalid token",
"reason": "InvalidToken",
"authorization": "Bearer foo.bar.baz",
"status": 401
}
EDIT:
I see it only works on top level properties; is there a way to achieve what I'm trying to do here - mask nested properties aptly named?
Well technically this works, but I'm not sure it's something I want to take live considering performance hit:
const jp = require('jsonpath')
class Sanitized extends Writable {
write(object) {
console.log(JSON.stringify(
['authorization', 'bearer'].reduce((object, property) => {
jp.apply(object, `$..${property}`, token => token.replace(/[^.]+$/, 'REDACTED'))
return object
}, merge({}, object))))
}
}
...
const log = context.log = createLogger({
name: '_placeholder',
level: process.env.LOG_LEVEL || 'info',
streams: [{type: 'raw', stream: new Sanitized()}]
})
Related
i am currently building an frontend app to display a generated qr code from an api. I started to implement the code but got a problem with the parsing of the response
here is the frontend code with the call
<template>
<div>
<p>test</p>
</div>
</template>
<script>
// Configuration
let myConfiguration = {
"Account" : "CH4431999123000889012",
"CreditorName" : "Muster AG",
"CreditorAddress1" : "Hauptstrasse 1",
"CreditorAddress2" : "8000 Zürich",
"CreditorCountryCode" : "CH",
"DebtorName" : "LivingTech GmbH",
"DebtorAddress1" : "Dörflistrasse 10",
"DebtorAddress2" : "8057 Zürich",
"DebtorCountryCode" : "CH",
"Amount" : "1.50",
"ReferenceNr" : "21000000000313947143000901",
"UnstructuredMessage" : "Mitteilung zur Rechnung",
"Currency" : "CHF",
"QrOnly" : "false",
"Format" : "PDF",
"Language" : "DE"
}
// Call function to create invoice
let myFile = generateQrInvoice(myConfiguration);
// Work with binary data
if(myFile != null) {
// ...
}
function generateQrInvoice(myRequestConfiguration) {
// Main configuration
let myEndpointUrl = "http://qrbillservice.livingtech.ch";
let myEndpointPath = "/api/qrinvoice/create/";
let myApiKey = "(falseApiKey)";
// GET parameters
let myGetParams = new URLSearchParams(myRequestConfiguration);
// Perform request
fetch(myEndpointUrl + myEndpointPath + "?" + myGetParams, {
method: "GET",
mode: "cors",
cache: "no-cache",
headers: {
"APIKEY": myApiKey,
"Accept": "application/json"
}
}).then(function (myResponse) {
try {
// Check status
if(myResponse.status == 200) {
// Read and parse JSON
let myJsonObject = JSON.parse(myResponse);
// Check if error
if(myJsonObject["isSuccessed"] == "true") {
if("base64Content" in myJsonObject && myJsonObject["base64Content"].trim() != "") {
// E.g. send file to client
let myBlob = new Blob(atob(myJsonObject["base64Content"]), {type: "application/pdf"});
let myBlobUrl = URL.createObjectURL(myBlob);
window.open(myBlobUrl);
// Return data
return atob(myJsonObject["base64Content"]);
} else {
throw "no data provided";
}
} else {
throw myJsonObject["message"];
}
} else {
throw "status code " . myResponse.status;
}
}
catch(e) {
// Handle exception
console.warn("Error: " + e.message, e);
return null;
}
}).catch(function (err) {
// Handle exception
console.warn("Error: " + err.message, err);
return null;
});
}
</script>
and here is the response i get when i inspect on the browser :
Error: Unexpected token 'o', "[object Response]" is not valid JSON SyntaxError: Unexpected token 'o', "[object Response]" is not valid JSON
at JSON.parse (<anonymous>)
at app.vue:61:42
I didn't write the apikey here but it is written on my code.
As it has been a long time since i didn't code like this, i don't really see yet how to tackle the problem. I tried to test with postman but it appears my request is not good yet.
If someone has an idea, i would be very happy to learn.
Thank you very much in advance,
Eugene
So i test myResponse and it is a JSON.
However the problem remains : i saw in the console that the api answers successfully api response
So i figured that i could just replace
let myJsonObject = JSON.parse(myResponse)
by
let myJsonObject = myResponse
and try to see what goes.
Now it goes directly in the catch(e) and send me an error response.
It looks like in my code, i don't go in the right direction to use the information i got from the api.
Here is partially the information i got : {"isSuccessed":true,"statusCode":200,"mimeType":"application/pdf","message":"QrBill is successfully generated","isQrOnly":false,"errors":"null","base64Content":(here is the content, i didn't added because it is quite long)}
my question therefore is how could recover the pdf and show it to the end user?
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
My API returns a JSON object to angular function
I need to fetch the value of the key in that JSON.
If I print the value directly on the console, there is no error.
My Angular Code :
submit() : void {
console.log("FORM SUBMITTED")
console.log(JSON.stringify(this.register.value, undefined, 2));
this._registerService.register(this.register.value)
.subscribe(
data => {
console.log("DATA : ", JSON.stringify(data, undefined, 2));
console.log("Status : " + data.status);
if (data.status == "duplicate") {
console.log("DUPLICATE");
} else if (data.status == "success") {
console.log("SUCCESS");
}
},
error => {
console.log("ERRORrrr : ", JSON.stringify(error, undefined, 2));
this._router.navigate(['/500']);
}
)
}
In the above code
console.log("DATA : ", JSON.stringify(data, undefined, 2));
Works Fine.
It shows the data :
But If I try to fetch the value of "status" in "data",
console.log("Status : " + data.status);
It gives error :
error TS2339: Property 'status' does not exist on type 'Object'.
I need to use the value of status in if statement
Please help in getting the value of data.status
I don't know which version of rxjs you use, but in the current version you have to catch errors of Observables with catchError().
This would be my solution:
register(body: any): Observable<{status: string, summary: string, details: string}> {
return this._http.post(
'localhost:3000/register', body,
{observe: 'body'}).pipe(catchError(this.handleError));
}
Maybe that will solve your problem.
Your .register method seems to be returning a Observable<object>, therefore the TS compiler gives you this error. Perhaps it's better to make it a generic method:
register<T>(body: any) {
return this._http.post<T>(
'localhost:3000/register',
body,
{ observe: 'body' }
).catch(this.handleError);
}
Which you can call in your component:
this._registerService.register<RegisterData>(this.register.value).subscribe((data) => {
if (data.status) {
// this will not throw a compiler error anymore as it will be of type RegisterData
}
});
with the interface being:
export interface RegisterData {
status: string;
summary: string;
details: string;
}
I observed that the object which was returned was an associative array.
So I was able to parse the associative array like :
console.log(data["status"]);
and I was able to convert this array to JSON by :
let dataJson = JSON.parse(JSON.stringify(data))
After this conversion I could access the JSON Key value by :
console.log(dataJson.status);
I have a problem with my application in angular2. I need to connect to api to retrieve records to my Persons [] class. I want to use the second method to get people with individual id. I do the same way as in the tutorial on the Angular site but unfortunately I still have a fault
ERROR TypeError: Cannot read property 'Name' of undefined
This is my service
getPersons(): Promise<Person[]> {
var currentUser = JSON.parse(localStorage.getItem('currentUser'));
var token = currentUser.token;
let headers = new Headers({ 'Authorization': 'Bearer ' + token })
let options = new RequestOptions({ headers: headers });
return this.http.get(this.QuestionsUrl, options)
.toPromise()
.then(response => response.json() as Person[]);
}
getPerson(id: number): Promise<Person> {
return this.getPersons().then(persons => persons.find(person => person.Id === id));
}
My component:
export class PersonsComponent implements OnInit {
activePerson: any = {};
model: any = {};
constructor(private personService: PersonService, private route: ActivatedRoute, private location: Location) {
}
ngOnInit(): void {
this.route.paramMap.switchMap((params: ParamMap) => this.personService.getPerson(+params.get('Id')))
.subscribe(selected => this.activePerson = selected);
}
}
And html:
<body>
{{activePerson.Name}}
Try using
{{activePerson?.Name}}
With a question mark.
The issue is that the template attempts to display the value before the data is retrieved. At that point, activePerson is undefined. Hence the error message.
The "?" is called a safe navigation operator. It prevents navigating to the "dot" property (name in this example) unless the object to the left of the question mark has a value.
use
{{activePerson |json}}
to know if you are receiving any data
I am using below method to obtain workitem Ids with specific title from my VSTS extension. I am using REST API , Typescript and WIQL .
public getWorkItemsbyQueryFilter(): string[] {
try {
let query = "Select [System.Id] From WorkItems Where [System.WorkItemType] = '" + this.workItemType + "' AND [System.Title] contains 'ABC'";
var ids : string[];
var self = this;
var colURL = this.collectionURL +this.teamProject +"/_apis/wit/wiql?api-version=1.0"
var options = {
url: colURL,
username: this.username,
password: this.password,
domain: this.domain,
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body :{
'query': query
}
};
httpntlm.post(options, function(err,res) {
if(err) {
console.log("Error : +"+ err)
deferred.reject(err);
}
var obj = JSON.parse(res.body);
for (var index = 0; index < obj.workItems.length; index++) {
ids.push(obj.workItems[index].id);
}
return ids;
});
} catch (error) {
console.log("Failed to Get Work Item Ids :"+ error);
}
}
I got below error when I execute this method . As per my web research I couldn't find much to resolve this issue
Unhandled: must start with number, buffer, array or string
Next I have try this request in postman (chrome extension). I am getting new error in same. It seems like something wrong with Json ,but I couldn't figure out what exactly it is. Please be kind enough to show some light.
{"count":1,"value":{"Message":"Error converting value \"query\" to type 'Microsoft.TeamFoundation.WorkItemTracking.Web.Models.Wiql'. Path '', line 1, position 7.\r\n"}}
The body value must be the string if you want to use body, for example:
body:`{
'query': 'Select [System.Id] From WorkItems Where [System.WorkItemType] = "Bug" AND [System.Title] contains "bug"'
}`
Thanks a lot for help me out. I was able to figure it out and fix this issue. I have to use "json" instead of "body" to fix this issue (Please check below code ..However I still get same error in postman . Still trying to figure-out why its giving error).
var options = {
url: colURL,
username: this.username,
password: this.password,
domain: this.domain,
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
json :{
'query': query
}
};