next js redirects not working in production page - redirect

const withPlugins = require("next-compose-plugins")
const withBundleAnalyzer = require("#next/bundle-analyzer")({
enabled: process.env.ANALYZE === "true",
})
/**
* #type {import('next').NextConfig}
*/
const nextConfig = {
reactStrictMode: true,
async redirects() {
return [
{
source: "/",
destination: "/schedule/calendar",
permanent: false,
},
]
},
exportPathMap: async function () {
return {
"/": { page: "/schedule/calendar" },
}
},
}
const withTM = require("next-transpile-modules")([
"#fullcalendar/common",
"#fullcalendar/daygrid",
"#fullcalendar/interaction",
"#fullcalendar/react",
"#fullcalendar/timegrid",
])
module.exports = withPlugins([[withBundleAnalyzer({ nextConfig, target: "serverless" })], [withTM]], nextConfig)
This is my next.config.js file. In development page this working well, but in production page when i enter root page like 'example.com' show the /schedule/calendar page. Also i try to enter 'example.com/schedule/calendar' show the error This XML file does not appear to have any style information associated with it. I check aws s3 buckets i can't see schedule.html. How can i solve this problem

Related

Cookie does not appear to be sent via fetch or hapi server is unable to receive cookie

So I have a simple backend server created with Hapi API and the frontend I'm using fetch. These are on different ports so I have CORs enabled and all the sweet stuff. I'm currently trying to set a refresh token in the browser using a http only cookie. As far as I can verify, the http only cookie is being set in the browser when login function is completed. I'm currently trying to send the http only cookie back to the server so I can set up the refresh token route and I can't seem to send or even verify that http token is sent back to the server.
Here's the server setting.
"use strict";
require("dotenv").config();
const Hapi = require("#hapi/hapi");
const Jwt = require("#hapi/jwt");
const routes = require("./routes/routes");
exports.init = async () => {
const server = Hapi.server({
port: 3000,
host: "localhost",
routes: {
cors: {
origin: ["*"],
credentials: true,
},
},
});
require("./models");
await server.register(Jwt);
server.auth.strategy("jwt", "jwt", {
keys: { key: process.env.SECRET_KEY, algorithms: ["HS256"] },
verify: { aud: false, iss: false, sub: false, exp: true },
validate: false,
});
server.state("refresh", {
ttl: 1000 * 60 * 60 * 24,
isSecure: true,
isHttpOnly: true,
encoding: "base64json",
clearInvalid: true,
strictHeader: true,
isSameSite: "None",
});
server.route(routes);
return server;
};
process.on("unhandledRejection", (err) => {
console.log(err);
process.exit(1);
});
Here's the login request and returns the http only cookie. This part works, the http cookie is returned and set.
const validateUserAndReturnToken = async (req, h) => {
const user = await User.findOne({
$or: [{ email: req.payload.username }, { username: req.payload.username }],
});
if (user) {
const match = await bcrypt.compare(req.payload.password, user.passwordHash);
if (match) {
const token = await createToken(match);
const refreshToken = await createRefreshToken(match);
h.state("refresh", refreshToken);
return { id_token: token, user: formatUser(user) };
} else {
throw boom.notAcceptable("Username and password did not match.");
}
} else {
throw boom.notAcceptable("Username or email was not found.");
}
};
Here's the fetch request I'm using to test sending a http cookie only back. I have credential: include so I don't know what is problem?
import type { DateInfo } from "#/stores/application";
const api = "http://localhost:3000/report";
let token = localStorage.getItem("user-token");
const headers = new Headers();
headers.append("Authorization", `Bearer ${token}`);
headers.append("Content-Type", "application/json");
export const getJobReport = async (dateFilter: DateInfo) => {
let response = await fetch(
`${api}/${dateFilter.startDate}/${dateFilter.endDate}`,
{
method: "GET",
headers,
credentials: "include",
}
);
return await response.json();
};
I have checked the application tab as well as the network request so I know set cookie is being sent and set on the browser. The problem is I can't seem to get the cookie back from the browser when fetch request is sent back to the server.
Here's the code I'm using to just check the existence of the cookie. According to Hapi Doc , req.state[cookie-name] which in this case is 'refresh' should have the cookie value. Refresh is returning undefined so I went up one level and check for req.state and gets an empty object {}.
route
{
method: "GET",
path: "/report/{startDate}/{endDate}",
options: {
auth: "jwt",
state: {
parse: true,
failAction: "error",
},
validate: {
params: Joi.object({
startDate: Joi.string(),
endDate: Joi.string(),
}),
},
},
handler: handlers.report.getJobApplicationReport,
},
handler
const getJobApplicationReport = async (req, h) => {
console.log("TEST", req.state);
const start = new Date(req.params.startDate);
const end = new Date(req.params.endDate);
try {
const applications = await Application.find({
dateApplied: { $gte: start, $lt: end },
});
// 'Applied', 'In Process', 'Rejected', 'Received Offer'
const total = applications.length;
let rejectedCount = 0;
let inProcessCount = 0;
applications.forEach((app) => {
if (app.status === "Rejected") {
rejectedCount++;
}
if (app.status === "In Process") {
inProcessCount++;
}
});
return {
total,
rejectedCount,
inProcessCount,
};
} catch (error) {
console.log(error);
throw boom.badRequest(error);
}
};
I've looked through all the Hapi documentation, fetch documentation and stackoverflow question/answers but can't seem to find a solution. I can't verify whether it's the fetch request that's not sending the http only cookie or the server setting that's not parsing it. Any help to determine the issue or solution would be greatly appreciated.
I've looked through all the Hapi documentation, fetch documentation and stackoverflow question/answers but can't seem to find a solution. I can't verify whether it's the fetch request that's not sending the http only cookie or the server setting that's not parsing it. Any help to determine the issue or solution would be greatly appreciated.

Get DOM and control the data from router hook / Navigation Guards in vue3

I want to control the data after I enter the index page from quiz page, but I found that it's not possible to control the data by the method below, is it because the afterEach is global ?
Is there any other method that I can use to control the data inside index page when I came from the quiz page ?
I thought of using the vuex, if there's no other way, I'll try it.
this is my route:
const routes: RouteRecordRaw[] = [
{
path: '/',
component: () => import('layouts/MainLayout.vue'),
children: [
{
name: 'index',
path: '/',
component: () => import('pages/IndexPage.vue')
},
{
name: 'quiz',
path: '/quiz',
component: () => import('pages/QuizPage.vue')
},
],
},
this is my code in index:
setup() {
const router = useRouter()
const state = ref(1)
router.afterEach((to, from) => {
if (from.name === 'quiz') {
state.value = 2
}
})
return {
state,
}
}

How can I increment a counter variable in LoopBack 4 with a MongoDB datasource?

I'm trying to convert my Nodejs Express app to Loopback 4 and I can't figure out how to increment a counter. In my Angular 9 app when a user clicks an icon a counter is incremented. This works perfectly in Express
In Express
const updateIconCount = async function (dataset, collection = 'icons') {
let query = { _id: new ObjectId(dataset.id), userId: dataset.userId };
return await mongoController.update(
collection,
query,
{ $inc: { counter: 1 } },
function (err, res) {
logAccess(res, 'debug', true, 'function update updateIconLink');
if (err) {
return false;
} else {
return true;
}
}
);
};
I tried to first get the value of counter and then increment but every time I save VS Code reformats the code in an an unusual way. In this snippet I commented out the line of code that causes this reformatting. I can set the counter value, e.g. 100.
In Loopback 4
#patch('/icons/count/{id}', {
responses: {
'204': {
description: 'Icons PATCH success',
},
},
})
async incrementCountById(
#param.path.string('id') id: string,
#requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Icons, {partial: true}),
},
},
})
icons: Icons,
): Promise<void> {
// let targetIcon = this.findById(id).then(icon => {return icon});
icons.counter = 100;
console.log(icons.counter);
await this.iconsRepository.updateById(id, icons);
}
How do I implement { $inc: { counter: 1 } } in Loopback 4?
Added to aid solution
My mongo.datasource.ts
import {inject, lifeCycleObserver, LifeCycleObserver} from '#loopback/core';
import {juggler} from '#loopback/repository';
const config = {
name: 'mongo',
connector: 'mongodb',
url: '',
host: '192.168.253.53',
port: 32813,
user: '',
password: '',
database: 'firstgame',
useNewUrlParser: true,
allowExtendedOperators: true,
};
// Observe application's life cycle to disconnect the datasource when
// application is stopped. This allows the application to be shut down
// gracefully. The `stop()` method is inherited from `juggler.DataSource`.
// Learn more at https://loopback.io/doc/en/lb4/Life-cycle.html
#lifeCycleObserver('datasource')
export class MongoDataSource extends juggler.DataSource
implements LifeCycleObserver {
static dataSourceName = 'mongo';
static readonly defaultConfig = config;
constructor(
#inject('datasources.config.mongo', {optional: true})
dsConfig: object = config,
) {
super(dsConfig);
}
}
Amended endpoint
#patch('/icons/count/{id}', {
responses: {
'204': {
description: 'Icons PATCH success',
},
},
})
async incrementCountById(
#param.path.string('id') id: string,
#requestBody({
content: {
'application/json': {
schema: getModelSchemaRef(Icons, {partial: true}),
},
},
})
icons: Icons,
): Promise<void> {
console.log(id);
// #ts-ignore
await this.iconsRepository.updateById(id, {$inc: {counter: 1}});//this line fails
// icons.counter = 101; //these lines will set the icon counter to 101 so I know it is connecting to the mongodb
// await this.iconsRepository.updateById(id, icons);
}
You can use the mongo update-operators.
Basically, you just have to set allowExtendedOperators=true at your MongoDB datasource definition (guide). After that, you can directly use these operators.
Usage example:
// increment icon.counter by 3
await this.iconsRepository.updateById(id, {$inc: {counter: 3}} as Partial<Counter>);
Currently, these operators are missing from the lb4 types so you must cheat typescript to accept them. It's ugly but that's the only solution I could find right now.
You can follow this issue to see what's going on with these operators.

How to configure API URL running on localhost on port 8080 in nuxt js?

I have the following vue file. My REST API base URL is http://localhost:8080/api/. When I access http://localhost:8080/api/dfc/system/docbases directly, I get the response as shown.
["gr_swy","SubWayX_DEMO"]
But I want to get the response through nuxt js which is running on http://localhost:3000/restapi/. I tried to follow all the articles, but not able to figure out where I'm doing wrong.
<template>
<div class="container">
{{docbases}}
</div>
</template>
<script>
import axios from "axios";
#import axios from "../../.nuxt/axios"; (tried both)
export default {
methods: {
// asyncData({ req, params }) {
// return axios.get("http://localhost:8080/api/dfc/system/docbases")
// .then(res => {
// return { docbases: res.data };
// }).catch((e) => {
// error({ statusCode: 404, message: 'Not found' })
// })
// },
async asyncData ({ params }) {
const { data } = await axios.get('http://localhost:8080/api/dfc/system/docbases');
return { docbases: data }
}
},
head: {
title: "D2Rest"
}
};
</script>
My nuxt.config.js is like this: I tried changeOrigin with true and false both. Can you please help me what extra things I need to configure?
axios: {
proxy: true,
},
env: {
baseUrl: process.env.BASE_URL || 'http://localhost:3000'
},
proxy: {
'/api/': {
target: 'http://localhost:8080/',
pathRewrite: { "^/api": "" },
changeOrigin: false,
prependPath: false
}
},
Based on your configuration, I'm assuming you're using the Nuxt Axios module...
The problem seems to be that you're importing Axios unnecessarily, thus bypassing your axios configuration in nuxt.config.js. The Nuxt Axios module docs describe its usage in components:
export default {
async asyncData({ $axios }) {
const ip = await $axios.$get('http://icanhazip.com')
return { ip }
}
}
Note the destructured parameter $axios. Use that parameter instead of importing your own instance of axios (i.e., don't do import axios from 'axios'), which is not the same as the one configured by Nuxt. No other imports are needed for $axios.
Proxy URL
Another problem is that your explicitly requesting the proxy address in the URL, but that should be excluded:
// const { data } = await $axios.get('http://localhost:8080/api/dfc/system/docbases'); // DON'T DO THIS
const { data } = await $axios.get('/api/dfc/system/docbases');
Sorry, I didn't enable Cross Origin in my java code. I have enabled now and it's resolved.
#CrossOrigin(origins = "http://localhost:3000")

Braintree PCI compliance issue

I have been continuously getting an email by brain tree on PCI Compliance regards and need confirmation on following two things which have been asked.
What is the Braintree payment integration method on our website? (Hint: It’s one of these)
Drop in UI or hosted field
Braintree SDK Custom integration
Following is the javascript code we've used . I went through the Braintree site on this regards but couldn't conclude upon this.
Additional Notes : We've made some changes on braintree vendor file.
var subscribed_user = "1";
$('#cc').on('click', function (e) {
$('#cc-info').show().attr('aria-hidden', true).css('visibility', 'visible');
});
var button = document.querySelector('#paypal-button');
var button1 = document.querySelector('#card-button');
var form = document.querySelector('#checkout-form');
var authorization = 'AuthHeaderxxxxxxxx=';
// Create a client.
braintree.client.create({
authorization: authorization
}, function (clientErr, clientInstance) {
// Stop if there was a problem creating the client.
// This could happen if there is a network error or if the authorization
// is invalid.
if (clientErr) {
console.error('Error creating client:', clientErr);
return;
}
/* Braintree - Hosted Fields component */
braintree.hostedFields.create({
client: clientInstance,
styles: {
'input': {
'font-size': '10pt',
'color': '#e3e3e3 !important; ',
'border-radius': '0px'
},
'input.invalid': {
'color': 'red'
},
'input.valid': {
'color': 'green'
}
},
fields: {
number: {
selector: '#card-number',
placeholder: '4111 1111 1111 1111',
},
cvv: {
selector: '#cvv',
placeholder: '123'
},
expirationDate: {
selector: '#expiration-date',
placeholder: '10/2019'
}
}
}, function (hostedFieldsErr, hostedFieldsInstance) {
if (hostedFieldsErr) { /*Handle error in Hosted Fields creation*/
return;
}
button1.addEventListener('click', function (event) {
event.preventDefault();
hostedFieldsInstance.tokenize(function (tokenizeErr, payload) {
if (tokenizeErr) { /* Handle error in Hosted Fields tokenization*/
document.getElementById('invalid-field-error').style.display = 'inline';
return;
}
/* Put `payload.nonce` into the `payment-method-nonce` input, and thensubmit the form. Alternatively, you could send the nonce to your serverwith AJAX.*/
/* document.querySelector('form#bt-hsf-checkout-form input[name="payment_method_nonce"]').value = payload.nonce;*/
document.querySelector('input[name="payment-method-nonce"]').value = payload.nonce;
form.submit();
button1.setAttribute('disabled', 'disabled');
});
}, false);
});
// Create a PayPal component.
braintree.paypal.create({
client: clientInstance,
paypal: true
}, function (paypalErr, paypalInstance) {
// Stop if there was a problem creating PayPal.
// This could happen if there was a network error or if it's incorrectly
// configured.
if (paypalErr) {
console.error('Error creating PayPal:', paypalErr);
return;
}
if ($('select#paypal-subs-selector option:selected').val() == '') {
button.setAttribute('disabled', 'disabled');
}
$('select#paypal-subs-selector').change(function () {
if ($('select#paypal-subs-selector option:selected').val() == '') {
button.setAttribute('disabled', 'disabled');
} else {
// Enable the button.
button.removeAttribute('disabled');
}
});
button.addEventListener('click', function () {
if(subscribed_user) {
// Popup Error for changing subscription.
swal({
html: true,
title: "",
text: "You are cancelling in the middle of subscription.<br/>If you do so you will not be refunded remaining days of your subscription.",
confirmButtonColor: '#605ca8',
confirmButtonText: 'Yes',
showCancelButton: true,
confirmButtonColor: "#DD6B55",
confirmButtonText: "Proceed !",
closeOnConfirm: true
}, function (isConfirm) {
if (isConfirm) {
show_payment_methods(paypalInstance);
}
});
} else{
show_payment_methods(paypalInstance);
}
}, false);
});
});
Any help would be highly appreciated.
Your code says Braintree - Hosted Field component And you don’t use anything like this which I found by searching “Braintree api”. I think you’re safe to say you use hosted fields.