Problem with routing css on my Node Express server - css

I am building a back-end for my web page, with file structure like this:
public
css
main.css
main_b.css
index.hbs
index_b.hbs
server
server.js
Styling sheets are referenced in index files by link attributes containing:
rel="stylesheet" type="text/css" href="main.css"
rel="stylesheet" type="text/css" href="main_b.css"
Here is my server.js :
const path = require('path');
const fs = require('fs');
const express = require('express');
const app = express();
const hbs = require('hbs');
hbs.registerPartials(path.join(__dirname, '../public/partials'));
app.set('view engine', 'hbs');
app.use(express.static(path.join(__dirname, '../public/css')));
// activity logger
app.use((req, res, next) => {
const now = new Date().toString();
const logEntry = `${now}: ${req.headers.host} ${req.method}${req.url}`;
fs.appendFile(path.join(__dirname, '../server/server.log'), logEntry.concat('\n'), (error) => {
if (error) {
console.log(error);
}
});
process.env.route = req.path;
next();
});
app.get('*', (req, res) => {
switch (process.env.route) {
case '/': // home page
res.render('../public/index.hbs');
break;
case '/b': // basic layout
res.render('../public/index_b.hbs');
break;
default: // unknown routes
res.render('../public/index.hbs');
}
});
app.listen(3000);
On requesting localhost:3000, log entry is ok:
Thu Jan 24 2019 07:57:08 GMT+0200 (Eastern European Standard Time): localhost:3000 GET/
On requesting localhost:3000/abc, log entry is also ok:
Thu Jan 24 2019 07:57:08 GMT+0200 (Eastern European Standard Time): localhost:3000 GET/abc
And the problem shows on testing requests with sub-routes like localhost:3000/abc/def, css doesn't render and the log entry is :
Thu Jan 24 2019 08:04:55 GMT+0200 (Eastern European Standard Time): localhost:3000 GET/abc/def
Thu Jan 24 2019 08:04:56 GMT+0200 (Eastern European Standard Time): localhost:3000 GET/abc/teamk-reset.css
Thu Jan 24 2019 08:04:56 GMT+0200 (Eastern European Standard Time): localhost:3000 GET/abc/main.css
I saw that part of the route is used to amend the css lookup path,
and tried to solve the problem by index and redirect properties of the options object in Express.static(), but no success.
Would be glad to receive some directions/ reference,
otherwise probably I should refactor my route querying approach.

I found the issue with my code,
Styling sheets should be referenced in index files by link attributes containing:
rel="stylesheet" type="text/css" href="/main.css"
rel="stylesheet" type="text/css" href="/main_b.css"
, their names prepended with '/' for correct lookup URL construction.

Related

Not able to get http response from a third party API when code deployed to azure function app, in debug mode its working fine

I have created an azure http trigger (also tried with timer trigger) function and it is calling an third party API with necessary params as content header. Locally in VS Code (debug mode), it's working fine. I am getting desired response (getting token if we call token end point as well as proper response if we call another end point by passing token). Even with postman I am getting correct response.
But when I deployed this function to azure function app, it's not getting response from both endpoint. (either from token one or if I pass hardcoded token copied from postman to second endpoint).
In logs, I can see function being called and when I am logging response I am getting a large html text(don't know what is that)
Is it possible that third party API is blocking or restricting calls from azure function(though it's working locally or with postman if we pass proper values)
Tried everything but can' find out the exact issue. I have verified I am passing correct values as grant_type, client_Id, client_secret, username, password, scope)
Have pasted below sample piece of code:
private async Task<Token> GetToken()
{
try{
HttpContent content = new FormUrlEncodedContent(new Dictionary<string, string>
{
{"grant_type", Environment.GetEnvironmentVariable("test-grant-type")},
{"username", Environment.GetEnvironmentVariable("test-username")},
{"password", Environment.GetEnvironmentVariable("test-password")},
{"client_id", Environment.GetEnvironmentVariable("test-client-id")},
{"client_secret", Environment.GetEnvironmentVariable("test-client-secret")},
{"scope", Environment.GetEnvironmentVariable("test-scope")}
});
HttpClient client = new HttpClient();
string tokenEndPoint = Environment.GetEnvironmentVariable("test-tokenApiEndPoint");
//calling API
HttpResponseMessage messageResult = await client.PostAsync(tokenEndPoint, content);
_logger.LogInformation($"Log Info: GetToken method: httpResponseMsg: {messageResult}");
string apiResponse = messageResult.Content.ReadAsStringAsync().Result;
_logger.LogInformation($"Log Info: GetToken method: apiResponse: {apiResponse}");
Token resTokenModel = JsonConvert.DeserializeObject<Token>(apiResponse);
}
catch (System.Exception ex)
{
_logger.LogError($"Exception : GetToken Method: Exception: {ex.Message}");
throw new Exception(ex.Message);
}
return resTokenModel;
}
Log html response sample (it's not complete as it is very large), Log1:
2022-06-29T08:30:05.490 [Information] Log Info: GetToken method: httpResponseMsg: StatusCode: 200, ReasonPhrase: 'OK', Version: 1.1, Content: System.Net.Http.HttpConnectionResponseContent, Headers:{Cache-Control: no-store, no-cachePragma: no-cacheStrict-Transport-Security: max-age=31536000; includeSubDomainsX-Content-Type-Options: nosniffX-Frame-Options: DENYLink: <https://aadcdn.msauth.net>; rel=preconnect; crossoriginLink: <https://aadcdn.msauth.net>; rel=dns-prefetchLink: <https://aadcdn.msftauth.net>; rel=dns-prefetchX-DNS-Prefetch-Control: onP3P: CP="DSP CUR OTPi IND OTRi ONL FIN"x-ms-request-id: 18670f19-3bec-4556-9b66-2c3760855300x-ms-ests-server: 2.1.13006.6 - WEULR1 ProdSlicesX-XSS-Protection: 0Set-Cookie: buid=0.AQIANaKxxxx_PBbRZsxxxx_PzErkPdDcCAdAA.xxxx--DLA3VO7QrddgJg7WevrDRjJU0T4KWPoylW2bC-ExpJHweIFWSInAdxjVwFITAQNF_FKbJPKHxxxxxp9ivEPYDacemz4wUo_sc04zyJbXjfz-2bVvxUz-AgAA; expires=Thu, 28-Jul-2022 08:30:05 GMT; path=/; secure; HttpOnly; SameSite=NoneSet-Cookie: fpc=AsZ-7OJNXMJAsZa7WVUJsyzxSauWAQAAAAyzTNoOAAAA; expires=Thu, 29-Jul-2022 08:30:05 GMT; path=/; secure; HttpOnly; SameSite=NoneSet-Cookie: esctx=AQABAAAAAAD--DLA3VO7QrddgJg7WevrvlcjjHs6JSFKoM9RHgIe1sGicQYOARxxxxwtTCtFHUZ7DawxrkQC4x3uxxkXSFkTTUgthZA1MEqk-Pmv2mzfkL9xBHg1V-LSzxeaWxtB38SA--OJKRBbdBVRR0D80RGqwGWTn5bm4XeaaWFCt5SYYet_q1fuHwxUMe7OXIuQgAA; domain=.login.microsoftonline.com; path=/; secure; HttpOnly; SameSite=NoneSet-Cookie: x-ms-gateway-slice=estsfd; path=/; secure; httponlySet-Cookie: stsservicecookie=estsfd; path=/; secure; httponlyDate: Tue, 28 Jun 2022 08:30:04 GMTContent-Type: text/html; charset=utf-8Expires: -1Content-Length: 195652}
from below html, I can only understand "Sign in to your account" but where to sign, Log2:
2022-06-28T08:30:05.492 [Information] Log Info: Synergi Repo: GetToken method: apiResponse:<!-- Copyright (C) Microsoft Corporation. All rights reserved. --><!DOCTYPE html><html dir="ltr" class="" lang="en"><head><title>Sign in to your account</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=2.0, user-scalable=yes"><meta http-equiv="Pragma" content="no-cache"><meta http-equiv="Expires" content="-1"><link rel="preconnect" href="https://aadcdn.msauth.net" crossorigin><meta http-equiv="x-dns-prefetch-control" content="on"><link rel="dns-prefetch" href="//aadcdn.msauth.net"><link rel="dns-prefetch" href="//aadcdn.msftauth.net"><meta name="PageID" content="ConvergedSignIn" /><meta name="SiteID" content="" /><meta name="ReqLC" content="1033" /><meta name="LocLC" content="en-US" /><meta name="referrer" content="origin" /><meta name="format-detection" content="telephone=no" /><noscript><meta http-equiv="Refresh" content="0; URL=https://login.microsoftonline.com/jsdisabled" /></noscript><meta name="robots" content="none" /><script type="text/javascript">//<![CDATA[$Config={"fShowPersistentCookiesWarning":false,"urlMsaSignUp":"https://login.live.com/oauth20_authorize.srf?response_type=code\u0026client_id=5xxx2-085c-xxxx-bf88-xxxxx8\u0026scope=openid+profile+email+offline_access\u0026response_mode=form_post\u0026redirect_uri=https%3a%2f%2flogin.microsoftonline.com%2fcommon%2ffederation%2foauth2msa\u0026state=rQQIxxxxxxFM4lbVARUISEBAuDmwnlYp99Z8dGDEFtIWogJQGEUCQ4n-_SE845sZ2UgBj5GZkYChISYycEC3QBJIREp0wIMSPBABJbO-KUFYnlLe99f-87Wxxxxkk1A8g9i0b-pawoLCQ6buGcLDlxEf2H_549xxxxvH95ugLnroRzxCot6m-DEWpr2E0_Xk7HicVcOaIUPhlJF8XSvvwZgAsAPADbzJYdaFAufQMQtA2LmBpASIaAgriAkEAjR6tf8fLM2TNfM6YhieZtvFB7ka_3-ahzdGrdTmnLvjlZXIxrK4FJ0k6sWT-Ox5qlhGJa1enI-iYRPNU_QMOFlrRnLrlQ0bNH1y3Goedpfux2982_DHb2puAy4SmU67ugsUoqztKOnUxxxxx4PMkZs0Sp1GIaYZy_EJnGgbwgTWowz5mAfE-FmyDZPEhmpPYiDGEKE2dCx7QzCmAt9GhjQtlwR2Dwj84V2d2FJBU2xl3mVxrS38LJQsijF1LQI9G1uQlwNCHSRS6AjmDBIpuX6xnahGPW5ksGXApjMgN0Z8Hw26_H4fPfYz1NXlp6IsnPjXju3PasnA0MuXsNdtFLt9thyO0zZsoqvxiuN9bONOg4vLEbDxsUzdnVQO4089KgIfhfBw325rbn_1P7iAHh3MLd7aOfbqzf3nz7-de4P0\u0026estsfed=1\u0026uaid=71c115c676664cc9bad0639fd6e7c4bf\u0026signup=1\u0026lw=1\u0026fl=easi2\u0026fci=7e7dac8e-5abd-4b36-b3f3-f312b90f7437","urlMsaLogout":"https://login.live.com/logout.srf?iframed_by=https%3a%2f%2flogin.microsoftonline.com","urlOtherIdpForget":"https://login.live.com/forgetme.srf?iframed_by=https%3a%2f%2flogin.microsoftonline.com","showCantAccessAccountLink":true,"urlGitHubFed":"https://login.live.com/oauth20_authorize.srf?response_type=code\u0026client_id=xxx-085c-xx-bf88-xxx\u0026scope=openid+profile+email+offline_access\u0026response_mode=form_post\u0026redirect_uri=https%3a%2f%2flogin.microsoftonline.com%2fcommon%2ffederation%2foauth2msa\u0026state=rQQIAxxxVE9bNNAxxxISEBAuDmwnlYp99Z8dGDEFtIWogJQGEUCQ4n-_SE845sZ2UgBj5GZkYChISYycEC3QBJIREp0wIMSPBABJbO-KUFYnlLe99f-87WUAV5JUc7gSUVTkxxxx-pawoLCQ6buGcLDlxEf2H_549P1AjD41tibs2efvH95ugLnroRzxCot6m-DEWpr2E0_Xk7HicVcOaIUPhlJF8XSvvxxxbzJYdaFAxxxxxiAkEAjR6tf8fLM2TNfM6YhieZtvFB7ka_3-ahzdGrdTmnLvxxxrK4FJ0k6sWT-Ox5qlhGJa1enI-iYRPNU_QMOFlrRnLrlQ0bNH1y3Goedpfux2982_DHb2puAy4SmU67ugsUoqztKOnUymtrLWyW56kmRshQ14PMkZs0Sp1GIaYZy_EJnGgbwgTWowz5mAfE-FmyDZPEhmpPYiDGEKE2dCx7QzCmAt9GhjQtlwR2xxxxd2FJBU2xl3mVxrS38LJQsijF1LQI9G1uQlwNCHSRS6AjmDBIpxxxxsGXApjMxxx26_H4fPfYz1NXlp6IsnPjXju3PasnA0MuXsNdxxxvxiuN9bONOg4vLEbDxsUzdnVQO4089KgIfhfBw325rbn_1P7iAHh3MLd7aOfbqzf3nz7-de4P0\u0026estsfed=1\u0026uaid=71c115c676664cc9bad0639fd6e7c4bf\u0026fci=7e7dxxxx-b3f3-f312b90f7437\u0026idp_hint=github.com","fShowSignInWithGitHubOnlyOnCredPicker":true,"fEnableShowResendCode":true,"iShowResendCodeDelay":90000,"sSMSCtryPhoneData":"AF~Afghanistan~93!!!AX~Ă…land Islands~358!!!AL~Albania~355!!!Islands~358!!!AL~Albania~355!!!
---------
-- and so here is large html content as above ---
--------------------------------------------------------------------------------------------------
Exception log:
This is because in code we are parsing response (so below issue is because it tried to parse response html) - so this does not seems to be useful
2022-06-29T15:18:14.657 [Error] Exception : GetToken Method: Exception: Unexpected character encountered while parsing value: '<'. Path '', line 0, position 0.
2022-06-29T15:18:14.710 [Error] Exception : Method: Exception: One or more errors occurred. (Unexpected character encountered while parsing value: '<'. Path '', line 0, position 0.)
If anyone has faced similar issue or can give an idea what can be the cause, though it's hard to find just looking in to code
Thanks
Errors like "Unexpected character encountered while parsing value: '<'. Path '', line 0, position 0." are almost invariably JSON parse errors.
The most common reason for it to occur is when the string being deserialized is not actually valid JSON.
Also check if the file containing JSON string had [BOM - Byte Order Mark]. Try and remove the BOM to resolve the error.
Thanks to all who replied and viewed this thread.
We have found the actual problem and it's not from the code/development side. The vendor has migrated the API to azure server and now they have another level of authentication (might be azure Ad)
So the original authentication which I believes (JWT Oauth) is returning it's token but we are not authenticating azure one so that's might be the reason we are getting azure html page.
Now API team is looking what's need to be done. We can close this thread or if someone has any solution or suggestion they can share.
Thanks

How to correctly parse data from Firebase Realtime Database?

First encounter with RealtimeDatabse - My database structure looks like this:
I use this code to read the data:
Map<String, BookingItem> bookingMap={}; // Need to populate this
final db = FirebaseDatabase(databaseURL:"https:MYURL");
final fb = db.reference();
fb.child('1b***APkCeLs/Form Responses 1').once()
.then((DataSnapshot data) {
print(jsonEncode(data.value)); // Shows up fine
var encod = jsonEncode(data.value);
try { // Problem here
// Need some code help with getting the data into MAP format please
} on Exception catch(e) {
print ('Error: $e');
}
debugPrint(bookingList.toString());
}).catchError((onError){
if (kDebugMode) print (onError);
});
My booking item class is simple:
class BookingItem {
String email;
//String chooseYourBookingLocation;
BookingItem({required this.email});//, required this.chooseYourBookingLocation});
BookingItem.fromJson(Map<String, dynamic> json)
: //chooseYourBookingLocation = json['Choose your booking location'],
email = json['Email'];
}
I want - Fri Jul 09 2021 07:33:09 GMT+0100 (British Summer Time) as key and BookingItem object with sub-details as a value.
I want to just start by grabbing the email and then the rest in the next steps.
End goal is to have BookingItem Map with all the details so I can update field/fields later as well.
jsonEncode prints this on the screen
{"Fri Jul 09 2021 07:33:09 GMT+0100 (British Summer Time)":{"Additional Information":"","Email":"litl.com","First Name":"Laura","Choose your booking location":"Brentwood","Time":"13:00","Last Name":"Irving","Phone Number":"074","Number of Guests":5,"Timestamp":"2021-07-09T06:33:09.675Z","Date":"","Email Address":""},"Fri Jul 09 2021 10:51:06 GMT+0100 (British Summer Time)":{"Additional Information":"","Email":"sa***uk.com","First Name":"Sacha","Choose your booking location":"Brentwood","Time":"18:30","Last Name":"Leal","Phone Number":"07**4","Number of Guests":2,"Timestamp":"2021-07-09T09:51:06.939Z","Date":"","Email Address":""},"Fri Jul 09 2021 12:02:22 GMT+0100 (British Summer Time)":{"Additional Information":"","Email":"nic**om","First Name":"Nicola","Choose your booking location":"Hatfield","Time":"15:00","Last Name":"Coan","Phone Number":"07***4","Number of Guests":2,"Timestamp":"2021-07-09T11:02:22.663Z","Date":"","Email Address":""},"Fri Ju...
I just want to simply do the following to start with:

CORS error when making Axios calls to Cloudrun service from Firebase hosted app

This looks to be pretty obvious but I've been trying to figure it out for a couple of days now and still can't get it to work. Please, can someone point out what I'm missing.
I'm trying to make an axios call to my cloud run service from my firebase hosted SPA. To isolate the issue I followed the steps outlined in the [firebase tutorial for cloud run] (https://firebase.google.com/docs/hosting/cloud-run#node.js)
Step 4 of the tutorial talks about setting up rewrite to use the firebase domain as a proxy to your cloud run service. It says that the helloworld service would be reachable via
Your Firebase subdomains:
projectID.web.app/helloworld and projectID.firebaseapp.com/helloworld
So I follow the steps and deploy the service. Then I try to make an axios call to the service from the SPA like below
testHelloWorld () {
axios.get(`https://myProjectId.firebaseapp.com/helloworld`)
.then((data) => {
console.log(data)
})
.catch(ex => {
console.error(ex)
})
})
}
But then I get the CORS error
Access to XMLHttpRequest at 'https://myProjectId.firebaseapp.com/helloworld' from origin 'https://myFirabaseApp.firebaseapp.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
This answer states that this should be possible so I'm not sure what I'm doing wrong.
N.B:
While debugging, I updated the node app from the tutorial to add cors support like below. Still didnt work.
const express = require('express');
const app = express();
const cors = require('cors'); //Imported and added this
app.use(cors()); // Used here
app.get('/', (req, res) => {
console.log('Hello world received a request.');
const target = process.env.TARGET || 'World';
res.send(`Hello ${target}!`);
});
const port = process.env.PORT || 8080;
app.listen(port, () => {
console.log('Hello world listening on port', port);
});
So the question here is, how do I make an Axios/AJAX call to my cloud run service using the firebase rewrite rule?
Please check if you have installed cors: npm install cors.
Please check if the 2 following options can solve your issue:
1= Use the following code :
app.use(cors({origin:true,credentials: true}));
2) If the previous didn't work, please use the following code:
app.get('/', (req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
console.log('Hello world received a request.');
}
Please let me know if it works for you.

Firebase HTTP Cloud Function HTTP error code 403

since 28-03-2020 all my HTTP cloud functions are in error. Before my last update, they were working fine. I changed only few things and after the last deploy I got this error:
<html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>403 Forbidden</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Forbidden</h1>
<h2>Your client does not have permission to get URL <code>/api/v0/.../</code> from this server.
</h2>
<h2></h2>
</body>
</html>
All the changes I did doesn't refer to the HTTP function implementation only in the BI.
Is there someone else with the same error? From the Firebase Status Console, it seems that firebase is not experiencing any error https://status.firebase.google.com/
EDIT: added an extract on how I initialize the HTTP cloud functions.
'use strict';
// node import
const cors = require('cors')({ origin: true });
const functions = require('firebase-functions');
const admin = require('firebase-admin');
// Setting timeout and memory for the deploy
const runtimeOpts = {
timeoutSeconds: 540,
memory: '2GB'
}
admin.initializeApp();
exports.exportMultipleDataToCSV = functions
.runWith(runtimeOpts)
.https.onRequest((request, response) => {
cors(request, response, () => {
if (request.method === 'PUT') response.status(403).send('Forbidden!');
if (request.method === 'DELETE') response.status(403).send('Forbidden!');
if (request.method === 'POST') response.status(403).send('Forbidden!');
// BI
let data = MY-BI;
response.status(200).set('Access-Control-Allow-Origin', '*').send(data);
});
});
I'm using the library "request" that I just saw that has been deprecated 2 months ago. It could be the problem? https://www.npmjs.com/package/request
Cloud Functions recently changed their default IAM policies for new functions to be restricted to project owners (previously it was allUsers, which allows for public access).
To prepare for this change, firebase-tools#7.7.0 added an IAM policy update on function creation that adds allUsers permissions. If you are using an older version of the CLI, new functions might be deployed in a restricted mode.
Importantly, however, this change should only apply to the creation of new functions -- if a function already exists and was only updated, no IAM changes should occur. If you're experiencing something else when updating functions, please file a detailed issue including debug logs with firebase-tools.

SignalR 1.2.2 Works in IE8 and Chrome 45 but fails in IE9 and FF 34

I am using SignalR 1.2.2, .NET 4.0, IIS Express (under development).
This is strange as usually things don't work in IE but work in other browsers. As this works in some browsers I am assuming it is a client and JS issue. I have the following code:
<script src="/scripts/html5shiv.min.js"></script>
<script src="/scripts/respond.min.js"></script>
<script src="/scripts/jquery-1.9.1.min.js"></script>
<script src="/scripts/bootstrap.min.js"></script>
<script src="~/Scripts/json2.min.js"></script>
<script src="~/Scripts/jquery.xdomainrequest.min.js"></script>
<script src="~/Scripts/jquery.signalR-1.2.2.min.js"></script>
<script src="/signalr/hubs"></script>
$(function () {
var info = $.connection.infoHub;
$.connection.hub.logging = true;
info.client.addNewMessageToPage = function (timestamp, status, message) {
appendToLog(timestamp, status, message);
};
$.connection.hub.start().done(function () {
var connectionId = $.connection.hub.id;
$("#connectionId").val(connectionId);
});
});
I get no notification in IE9/FF34 but works as expected in IE8/Chrome45.
I enabled CORS support. I added JSON2.js. I am still having the same problem.
On FF I am getting this error:
The connection to http://localhost:6677/signalr/connect?transport=serverSentEvents&connectionToken=Z2mxweQj-PocYsBHebUD4vqsBpBOVfU3vPZOEX5W09dampCExo-emJbYGe_gCz7iFN_tuHlnTjgUUeKz1ZXlcySsWQSOzaHQS8SE3N9Q_MzfUjSzr18mKOOqnk_lVtjdHi4LOmTbsN4q5tgXdZc_p15Ncq_cIgkwEyJoJoApXjbMB6k6vXwe_zQ5Aa_pB5iP0&connectionData=%5B%7B%22name%22%3A%22infohub%22%7D%5D&tid=6 was interrupted while the page was loading.
[16:11:28 GMT+0100 (GMT Standard Time)] SignalR: Fired ajax abort async = false.
jquery.....min.js (line 10)
[16:11:28 GMT+0100 (GMT Standard Time)] SignalR: Stopping the monitoring of the keep alive.
I am getting this while uploading a file to the server via full post (while the thread is still running before a page refresh).
Any ideas how I should progress in investigating this or a solution?

Resources