Skip to content

Commit

Permalink
refactor: fix middleware URL generation (#6688)
Browse files Browse the repository at this point in the history
* refactor(core): fix missing getBaseUrl method

* refactor(core): changed URL fetch methods

* refactor(core): removed unused test

* refactor(core): simplified the logic for URL

* Update packages/core/core/src/utils/nuxt/index.ts

Co-authored-by: daaf <44862757+dawid-ziobro@users.noreply.github.com>

* Update packages/core/core/src/utils/nuxt/_proxyUtils.ts

Co-authored-by: Lukas Borawski <lukas.borawski@gmail.com>

* refactor(core): changed the way to fetch url from config

* refactor(core): added URL to generate Urls

* refactor(core): removed URL checking, only validantion

* refactor(nuxt-module): added URL check as a hook

* refactor(nuxt-module): fixed URL generation in hook

* refactor(core): slim down the code for URL generation

* chore: removed non-used plugin `is-https`

* refactor(core):  fixed regex

* refactor(core): fixed tests for new approach

* refactor(nuxt-module): fixed configuration merge

* refactor(nuxt-module): fixed configuration merge

* refactor(nuxt-module): changed merge strategy

* refactor(nuxt-module): changed merge strategy

* chore: version bump for core and nuxt module

* chore: version bumop for missing packages

* docs: added documentation for the new release

* docs: migration guide update

* docs: migration guide update

* docs: migration guide update

Co-authored-by: Filip Sobol <filipsobol@users.noreply.github.com>

* docs: migration guide update

Co-authored-by: Filip Sobol <filipsobol@users.noreply.github.com>

* docs: migration guide update

Co-authored-by: Filip Sobol <filipsobol@users.noreply.github.com>

* refactor(nuxt-module): improved validation in server-url

* refactor(core): added error if the middlewareURL fails

* docs: added documentation for the new changes

* refactor: moved error to url generator

* chore: moved worming of missing middlwareUrl, docs update

* refactor(nuxt-module): fixed host and port checking

* chore: copy

* chore: copy

* docs: copy

* revert: middlware url notation

* refactor(nuxt-module): applied URL to generate url of API

* refactor(nuxt-module): removed serverUrl from package

* refactor(middleware): added serverUrl logic to package

* chore: version bump to 2.5.12-c

* feat(middleware): added missing Helmet package in nuxt and API

* refactor(core): added browser URL fetch for API

* chore: version bump to 2.5.12-c

* refactor(middleware): added HELMET options and default

* docs(middleware): added documentation for Helmet.js and middlewareUrl

* refactor: fixed logging information

* refactor(middleware): added missing flag to control `helmet`

* chore: types

* chore: version bump to 2.5.12-c

* fix: configs, data transfering

* chore: version bump to 2.5.12-c

* docs: update

* Update packages/core/docs/security/api-url.md

* chore: disabling helmet by defult

* test: proxyUtils base url fix

* chore: helmet options object brackets

* revert: console log

* docs: headers-security.md update

Co-authored-by: Filip Sobol <filipsobol@users.noreply.github.com>

* docs: headers-security.md update

Co-authored-by: Filip Sobol <filipsobol@users.noreply.github.com>

* docs: headers-security.md update

Co-authored-by: Filip Sobol <filipsobol@users.noreply.github.com>

* docs: headers-security.md update

Co-authored-by: Filip Sobol <filipsobol@users.noreply.github.com>

* chore: version bump to 2.5.12-c

* chore: versions alignment

* docs: update api-url.md

Co-authored-by: Filip Sobol <filipsobol@users.noreply.github.com>

* docs: update api-url.md

Co-authored-by: Filip Sobol <filipsobol@users.noreply.github.com>

* chore: removed un chaining

Co-authored-by: daaf <44862757+dawid-ziobro@users.noreply.github.com>

* chore: interpolation

Co-authored-by: daaf <44862757+dawid-ziobro@users.noreply.github.com>

* chore: types

* chore: condition fix

Co-authored-by: daaf <44862757+dawid-ziobro@users.noreply.github.com>

Co-authored-by: Lukas Borawski <lukas.borawski@gmail.com>

Co-authored-by: Filip Sobol <filipsobol@users.noreply.github.com>

Co-authored-by: Filip Sobol <sobol.filip@gmail.com>
  • Loading branch information
bloodf and filipsobol authored Apr 7, 2022
1 parent da4dc20 commit 12feb05
Show file tree
Hide file tree
Showing 23 changed files with 3,119 additions and 2,881 deletions.
4 changes: 2 additions & 2 deletions packages/core/cache/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vue-storefront/cache",
"version": "2.5.7",
"version": "2.5.12",
"license": "MIT",
"main": "lib/index.cjs.js",
"module": "lib/index.es.js",
Expand All @@ -12,7 +12,7 @@
"prepublish": "yarn build"
},
"dependencies": {
"@vue-storefront/core": "~2.5.7"
"@vue-storefront/core": "~2.5.12"
},
"peerDependencies": {
"@nuxtjs/composition-api": "^0.29.3"
Expand Down
10 changes: 6 additions & 4 deletions packages/core/core/__tests__/utils/nuxt/proxyUtils.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as utils from '../../../src/utils/nuxt/_proxyUtils';

describe('[CORE - utils] _proxyUtils', () => {
process.server = true;

it('returns proxy for defined api', () => {
const givenApi = {
getProduct: jest.fn()
Expand Down Expand Up @@ -32,13 +34,13 @@ describe('[CORE - utils] _proxyUtils', () => {
expect(utils.getIntegrationConfig(
{
$config: {
middlewareUrl: 'some-url'
middlewareUrl: 'http://localhost.com'
}
} as any,
{ someGivenOption: 1 }
)).toEqual({
axios: {
baseURL: 'some-url',
baseURL: 'http://localhost.com/api',
headers: {}
},
someGivenOption: 1
Expand All @@ -51,13 +53,13 @@ describe('[CORE - utils] _proxyUtils', () => {
expect(utils.getIntegrationConfig(
{
$config: {
middlewareUrl: 'some-url'
middlewareUrl: 'http://localhost.com'
}
} as any,
{}
)).toEqual({
axios: {
baseURL: 'some-url',
baseURL: 'http://localhost.com/api',
headers: {
cookie: 'xxx'
}
Expand Down
3 changes: 1 addition & 2 deletions packages/core/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vue-storefront/core",
"version": "2.5.8",
"version": "2.5.12",
"sideEffects": false,
"main": "lib/index.cjs.js",
"module": "lib/index.es.js",
Expand All @@ -15,7 +15,6 @@
"dependencies": {
"axios": "0.21.1",
"express": "^4.17.1",
"is-https": "^3.0.2",
"lodash-es": "^4.17.15",
"vue": "^2.6.11"
},
Expand Down
2 changes: 2 additions & 0 deletions packages/core/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import { Ref } from '@nuxtjs/composition-api';
import type { Request, Response } from 'express';
import { HelmetOptions } from 'helmet';

/**
* Default name of the cookie storing active localization code
Expand Down Expand Up @@ -845,6 +846,7 @@ export type IntegrationsSection = Record<string, Integration>

export interface MiddlewareConfig {
integrations: Record<string, Integration>;
helmet?: boolean | Readonly<HelmetOptions>;
}

export interface ApiClientFactoryParams<T, F = any> {
Expand Down
16 changes: 6 additions & 10 deletions packages/core/core/src/utils/nuxt/_proxyUtils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Context as NuxtContext } from '@nuxt/types';
import merge from 'lodash-es/merge';
import { ApiClientMethod } from './../../types';
import { Logger } from './../logger';

interface CreateProxiedApiParams {
givenApi: Record<string, ApiClientMethod>;
Expand All @@ -25,25 +26,20 @@ export const createProxiedApi = ({ givenApi, client, tag }: CreateProxiedApiPara
export const getCookies = (context: NuxtContext) => context?.req?.headers?.cookie ?? '';

export const getIntegrationConfig = (context: NuxtContext, configuration: any) => {
const baseURL = process.server ? context?.$config?.middlewareUrl : window.location.origin;
const cookie = getCookies(context);

if (context?.$config?.middlewareUrl) {
const { middlewareUrl } = context.$config;
return merge({
axios: {
baseURL: middlewareUrl,
headers: {
...(cookie ? { cookie } : {})
}
}
}, configuration);
if (process.server && context?.$config?.middlewareUrl) {
Logger.info('Applied middlewareUrl as ', context.$config.middlewareUrl);
}

return merge({
axios: {
baseURL: new URL(/\/api\//gi.test(baseURL) ? '' : 'api', baseURL).toString(),
headers: {
...(cookie ? { cookie } : {})
}
}
}, configuration);
};

1 change: 1 addition & 0 deletions packages/core/core/src/utils/nuxt/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export const integrationPlugin = (pluginFn: NuxtPlugin) => (nuxtCtx: NuxtContext
const injectInContext = createAddIntegrationToCtx({ tag, nuxtCtx, inject });
const config = getIntegrationConfig(nuxtCtx, configuration);
const client = axios.create(config.axios);

const api = createProxiedApi({ givenApi: configuration.api || {}, client, tag });

if (nuxtCtx.app.i18n.cookieValues) {
Expand Down
5 changes: 3 additions & 2 deletions packages/core/docs/.vuepress/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -191,10 +191,11 @@ module.exports = {
]
},
{
title: 'Miscellaneous',
title: 'Security',
collapsable: true,
children: [
['/miscellaneous/handling-cookies', 'Handling cookies']
['/security/headers-security', 'HTTP Headers security'],
['/security/api-url', 'Server Middleware URL']
]
},
{
Expand Down
15 changes: 0 additions & 15 deletions packages/core/docs/getting-started/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,6 @@ Every Vue Storefront project must contain two configuration files described belo

You can learn more about this file and available configuration options on the [Nuxt configuration file](https://nuxtjs.org/docs/directory-structure/nuxt-config/) page.

The only thing you have to configure when setting up a new project is the `middlewareUrl` property which defines the URL to the Server Middleware. Usually, it's your application domain followed by the `/api` path.

Example:

```javascript
// nuxt.config.js
export default {
publicRuntimeConfig: {
middlewareUrl: 'https://yourdomain.com/api/'
}
}
```

For the local development, set it to `http://localhost:3000/api/`.

### `middleware.config.js`

The `middleware.config.js` file is as essential as `nuxt.config.js`, but much simpler and likely smaller. It configures the Server Middleware used for communication with e-commerce platforms and contains sensitive credentials, custom endpoints, queries, etc.
Expand Down
5 changes: 3 additions & 2 deletions packages/core/docs/reference/changelog.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Changelog

## 2.5.8 (deprecated)
## 2.5.12

- **[BREAKING]** `middlewareUrl` is no longer required from the global config, however it should be provided to handle integration specific API calls
- Middleware and Nuxt Middleware [Helmet](https://github.com/helmetjs/helmet) added. ([6688](https://github.com/vuestorefront/vue-storefront/pull/6688)) [Heitor Ramon](https://github.com/bloodf)
- Revert the breaking change introduced in `2.5.7`, with the default behavior and the possibility to use Nuxt `middlewareUrl` as the endpoint definition. ([6688](https://github.com/vuestorefront/vue-storefront/pull/6688)) [Heitor Ramon](https://github.com/bloodf)

## 2.5.7

Expand Down
42 changes: 42 additions & 0 deletions packages/core/docs/reference/migrate/2.5.12/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Migrating projects to 2.5.12

## Update `nuxt.config.js`

In this release, we've added the optional `middlewareUrl` property to define the URL to the Server Middleware. Open the `nuxt.config.js` file and add the `middlewareUrl` property to the `publicRuntimeConfig` object as shown below.

:::warning
Make sure to pass the whole URL with protocol, port (if applicable), and suffix it with `/api/`.
:::

```javascript
// nuxt.config.js
export default {
publicRuntimeConfig: {
middlewareUrl: process.env.NODE_ENV === 'production'
? 'https://example.com/api/' // Your production URL
: 'http://localhost:3000/api/'
}
}
```

If you don't want to hardcode the URL in the configuration file, you can use environmental variables.

Example:

```javascript
// nuxt.config.js
export default {
publicRuntimeConfig: {
middlewareUrl: process.env.API_BASE_URL
}
}
```

Then add an entry in the `.env` file or use any other method for passing environmental variables that suits your needs.

Example:

```text
// .env
API_BASE_URL=https://example.com/api/
```
39 changes: 0 additions & 39 deletions packages/core/docs/reference/migrate/2.5.7/overview.md

This file was deleted.

4 changes: 2 additions & 2 deletions packages/core/docs/reference/migrate/index.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Migration guides

## 2.5.7
- [Overview](./2.5.7/overview.md)
## 2.5.12
- [Overview](./2.5.12/overview.md)

## 2.5.0
- [Overview](./2.5.0/overview.md)
Expand Down
40 changes: 40 additions & 0 deletions packages/core/docs/security/api-url.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Server Middleware URL

Internally we use Nuxt environment properties to get the URL of Server Middleware. However, you can change it by defining the `middlewareUrl` property in the `publicRuntimeConfig` object inside the `nuxt.config.js` file.

:::warning
Make sure to pass the whole URL with protocol, port (if applicable), and suffix it with `/api/`.
:::

```javascript
// nuxt.config.js
export default {
publicRuntimeConfig: {
middlewareUrl: process.env.NODE_ENV === 'production'
? 'https://example.com/api/' // Your production URL
: 'http://localhost:3000/api/'
}
}
```

If you don't want to hardcode the URL in the configuration file, you can use environmental variables.

Example:

```javascript
// nuxt.config.js
export default {
publicRuntimeConfig: {
middlewareUrl: process.env.API_BASE_URL
}
}
```

Then add an entry in the `.env` file or use any other method for passing environmental variables that suits your needs.

Example:

```text
// .env
API_BASE_URL=https://example.com/api/
```
62 changes: 62 additions & 0 deletions packages/core/docs/security/headers-security.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# HTTP Headers security

To improve the security of Vue Storefront applications, we preinstall the [Helmet](https://helmetjs.github.io/) security extension by default for Nuxt application and the [Server Middleware](/architecture/server-middleware.html).

In this document we show how to change the default configuration in both applications. For a list of all available options, see the [Helmet documentation](https://helmetjs.github.io/docs/).

## Configuring Helmet in Nuxt

`Helmet` is disabled by default. You can enable it using the `helmet` property in the `@vue-storefront/middleware/nuxt` module configuration. You can pass `true` to enable it with the default configuration or an object to use your custom configuration.

```javascript
// nuxt.config.js
export default {
modules: [
['@vue-storefront/middleware/nuxt', {
helmet: true
// or
helmet: {
// ...configuration
}
}]
]
}
```

```javascript
// nuxt.config.js
export default {
modules: [
['@vue-storefront/middleware/nuxt', {
helmet: {
// default configuration
crossOriginOpenerPolicy: false,
contentSecurityPolicy: false,
crossOriginEmbedderPolicy: false,
permittedCrossDomainPolicies: {
permittedPolicies: 'none'
}
}
}]
]
}
```

## Configuring Helmet in VSF Server Middleware

`Helmet` is disabled by default. You can enable it using the `helmet` property in the `middleware.config.js` file. You can either pass `true` to enable it with the default configuration or pass an object to use your custom configuration.

```javascript
// middleware.config.js
module.exports = {
helmet: {
// default configuration
crossOriginOpenerPolicy: false,
contentSecurityPolicy: false,
crossOriginEmbedderPolicy: false,
permittedCrossDomainPolicies: {
permittedPolicies: 'none'
}
}
};
```
2 changes: 1 addition & 1 deletion packages/core/health-check/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vue-storefront/health-check",
"version": "2.5.7",
"version": "2.5.12",
"description": "",
"main": "lib/module.js",
"scripts": {
Expand Down
Loading

0 comments on commit 12feb05

Please sign in to comment.