├── .chglog
├── CHANGELOG.tpl.md
├── RELEASE.tpl.md
├── config.yml
└── release-config.yml
├── .editorconfig
├── .eslintrc.js
├── .gitattributes
├── .github
├── dependabot.yml
└── workflows
│ ├── codeql-analysis.yml
│ ├── github-ci.yml
│ └── reuse-compliance.yml
├── .gitignore
├── .npmrc
├── .reuse
└── dep5
├── CHANGELOG.md
├── CONTRIBUTING.md
├── LICENSE.txt
├── LICENSES
└── Apache-2.0.txt
├── README.md
├── SECURITY.md
├── index.js
├── lib
├── discovery.js
├── less.js
├── properties.js
├── proxy-rewrite-cookies.js
└── proxy.js
├── package-lock.json
├── package.json
└── test
├── discovery_test.js
├── fixtures
├── discovery
│ ├── app-resources1
│ │ └── index.html
│ ├── app-resources2
│ │ └── foo
│ │ │ └── bar.htm
│ ├── resources1
│ │ └── my
│ │ │ └── ui
│ │ │ └── lib
│ │ │ └── .library
│ ├── resources2
│ │ └── my
│ │ │ └── legacy
│ │ │ └── ui
│ │ │ └── lib
│ │ │ └── my.legacy.ui.lib.library
│ ├── resources3
│ │ └── my
│ │ │ └── ui
│ │ │ └── l
│ │ │ └── .library
│ ├── test-resources1
│ │ └── my
│ │ │ └── ui
│ │ │ └── lib
│ │ │ └── qunit
│ │ │ └── MyControl.qunit.html
│ ├── test-resources2
│ │ └── my
│ │ │ └── legacy
│ │ │ └── ui
│ │ │ └── lib
│ │ │ └── MyControl.htm
│ └── test-resources3
│ │ └── my
│ │ └── ui
│ │ └── l
│ │ └── qunit
│ │ └── MyControl3.qunit.html
├── less
│ └── test
│ │ └── themes
│ │ └── mytheme
│ │ └── library.source.less
└── properties
│ └── test.properties
├── less_test.js
├── mergeUrls_test.js
├── properties_test.js
├── proxy-rewrite-cookies_test.js
├── proxy_ignore_remote_location_test.js
├── proxy_test.js
└── proxy_use_remote_location_test.js
/.chglog/CHANGELOG.tpl.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 | All notable changes to this project will be documented in this file.
3 | This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
4 |
5 | {{ if .Versions -}}
6 | A list of unreleased changes can be found [here]({{ .Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD).
7 | {{ end -}}
8 |
9 | {{ range .Versions }}
10 |
11 | ## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }}
12 | {{ range .CommitGroups -}}
13 | ### {{ .Title }}
14 | {{ range .Commits -}}
15 | - {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} [`{{ .Hash.Short }}`]({{ $.Info.RepositoryURL }}/commit/{{ .Hash.Long }})
16 | {{ end }}
17 | {{ end -}}
18 |
19 | {{- if .RevertCommits -}}
20 | ### Reverts
21 | {{ range .RevertCommits -}}
22 | - {{ .Revert.Header }}
23 | {{ end }}
24 | {{ end -}}
25 |
26 | {{- if .NoteGroups -}}
27 | {{ range .NoteGroups -}}
28 | ### {{ .Title }}
29 | {{ range .Notes }}
30 | {{ .Body }}
31 | {{ end }}
32 | {{ end -}}
33 | {{ end -}}
34 | {{ end -}}
35 |
36 | {{- if .Versions }}
37 | {{ range .Versions -}}
38 | {{ if .Tag.Previous -}}
39 | [{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}
40 | {{ end -}}
41 | {{ end -}}
42 | {{ end -}}
43 |
44 | ## 0.7.7 - 2019-07-01
45 |
46 | ### Fixes
47 | - proxy middleware
48 | - Removing 'secure' flag of cookies [#50](https://github.com/SAP/connect-openui5/pull/50)
49 |
50 | ### All changes
51 | [`0.7.6...0.7.7`](https://github.com/SAP/connect-openui5/compare/0.7.6...0.7.7)
52 |
53 |
54 | ## 0.7.6 - 2019-03-13
55 |
56 | ### Fixes
57 | - proxy middleware
58 | - Also strip 'secure' cookie flag at the end of the header [#41](https://github.com/SAP/connect-openui5/pull/41)
59 |
60 | ### All changes
61 | [`0.7.5...0.7.6`](https://github.com/SAP/connect-openui5/compare/0.7.5...0.7.6)
62 |
63 |
64 | ## 0.7.5 - 2018-10-09
65 |
66 | ### Other changes
67 | - Update less-openui5@0.6.0 [#27](https://github.com/SAP/connect-openui5/pull/27)
68 |
69 | ### All changes
70 | [`0.7.4...0.7.5`](https://github.com/SAP/connect-openui5/compare/0.7.4...0.7.5)
71 |
72 |
73 | ## 0.7.4 - 2018-05-18
74 |
75 | ### Other changes
76 | - Update less-openui5 to v0.5.3 [#25](https://github.com/SAP/connect-openui5/pull/25)
77 |
78 | ### All changes
79 | [`0.7.3...0.7.4`](https://github.com/SAP/connect-openui5/compare/0.7.3...0.7.4)
80 |
81 |
82 | ## 0.7.3 - 2018-03-12
83 |
84 | ### Other changes
85 | - Update dependencies ([`b8d59ea`](https://github.com/SAP/connect-openui5/commit/b8d59ea8cd1e2db46b5c5f0117f02ed40aa1a097))
86 | - Update copyright years ([`9091d54`](https://github.com/SAP/connect-openui5/commit/9091d5459126a6080a03b5db360c31d9d30c2665))
87 |
88 | ### All changes
89 | [`0.7.2...0.7.3`](https://github.com/SAP/connect-openui5/compare/0.7.2...0.7.3)
90 |
91 |
92 | ## 0.7.2 - 2017-07-18
93 |
94 | ### Fixes
95 | - proxy middleware
96 | - remove "secure" flag from cookies [#18](https://github.com/SAP/connect-openui5/pull/18)
97 |
98 | ### All changes
99 | [`0.7.1...0.7.2`](https://github.com/SAP/connect-openui5/compare/0.7.1...0.7.2)
100 |
101 |
102 | ## 0.7.1 - 2017-06-22
103 |
104 | ### Fixes
105 | - proxy middleware
106 | - fix no_proxy patterns with * wildcard [#16](https://github.com/SAP/connect-openui5/pull/16)
107 |
108 | ### Other changes
109 | - Travis CI: Test Node.js 4, 6 and 8 with npm v5 [#17](https://github.com/SAP/connect-openui5/pull/17)
110 |
111 | ### All changes
112 | [`0.7.0...0.7.1`](https://github.com/SAP/connect-openui5/compare/0.7.0...0.7.1)
113 |
114 |
115 | ## 0.7.0 - 2017-03-23
116 |
117 | ### Breaking changes
118 | - Drop support for Node.js v0.10 [#13](https://github.com/SAP/connect-openui5/pull/13)
119 |
120 | ### Features
121 | - less middleware
122 | - Support theme scopes (Belize Themes) [#15](https://github.com/SAP/connect-openui5/pull/15) (via [SAP/less-openui5#10](https://github.com/SAP/less-openui5/pull/10))
123 |
124 | ### All changes
125 | [`0.6.0...0.7.0`](https://github.com/SAP/connect-openui5/compare/0.6.0...0.7.0)
126 |
127 |
128 | ## 0.6.0 - 2016-04-25
129 |
130 | ### Breaking changes
131 | - less middleware
132 | - Set default of parser option `relativeUrls` to `true` [`4d5fca2 ` via less-openui5@0.2.0](https://github.com/SAP/connect-openui5/commit/4d5fca25954049eec4af53c8bd12c54d6ad020aa) (see [`00d892b `](https://github.com/SAP/less-openui5/commit/00d892b95c8c0401b8a61f1b1709dfc4a68cfa26))
133 |
134 | ### Features
135 | - less middleware
136 | - enable inline theming parameters [`4d5fca2`](https://github.com/SAP/connect-openui5/commit/4d5fca25954049eec4af53c8bd12c54d6ad020aa)
137 |
138 | ### All changes
139 | [`0.5.0...0.6.0`](https://github.com/SAP/connect-openui5/compare/0.5.0...0.6.0)
140 |
141 |
142 | ## 0.5.0 - 2016-01-20
143 |
144 | ### Features
145 | - proxy middleware
146 | - Add support for modifying the remote location via environment variable [`46c1e56`](https://github.com/SAP/connect-openui5/commit/46c1e56db46357fee59ee072e0c82516d5c17e9e)
147 |
148 | ### All changes
149 | [`0.4.1...0.5.0`](https://github.com/SAP/connect-openui5/compare/0.4.1...0.5.0)
150 |
151 |
152 | ## 0.4.1 - 2015-09-04
153 |
154 | ### Fixes
155 | - less middleware
156 | - Extend default options rather than assign with provided options [`5ae50cd`](https://github.com/SAP/connect-openui5/commit/5ae50cd753ef5e2a3ba2807a70877ef79b6ce433)
157 |
158 | ### All changes
159 | [`0.4.0...0.4.1`](https://github.com/SAP/connect-openui5/compare/0.4.0...0.4.1)
160 |
161 |
162 | ## 0.4.0 - 2015-01-12
163 |
164 | ### Features
165 | - proxy middleware
166 | - allow passing options for [http-proxy](https://github.com/nodejitsu/node-http-proxy#options) [`6ab9920`](https://github.com/SAP/connect-openui5/commit/6ab99201d5d2439ba55017ec8211b4dd8e5ed2a9)
167 |
168 | ### All changes
169 | [`0.3.0...0.4.0`](https://github.com/SAP/connect-openui5/compare/0.3.0...0.4.0)
170 |
171 |
172 | ## 0.3.0 - 2014-11-17
173 |
174 | ### Breaking changes
175 | - context middleware
176 | - removed (not needed anymore) [`7977fde`](https://github.com/SAP/connect-openui5/commit/7977fdeaf53a6caf9f4ef4f410bd01e13927be3c)
177 | - less middleware
178 | - changed `options` argument to [less-openui5](https://github.com/SAP/less-openui5) options [`bf6d596`](https://github.com/SAP/connect-openui5/commit/bf6d596d67c5915408dc6287d15baa6a5e311c3e)
179 |
180 | ### Fixes
181 | - proxy middleware
182 | - now respects the local proxy configuration (environment variables `HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`) when making requests [`483e137`](https://github.com/SAP/connect-openui5/commit/483e1377caa0e90e3f4be9cc8ca91b01b4581103)
183 | - less middleware
184 | - next should not be called after ending the response [`df71ca8`](https://github.com/SAP/connect-openui5/commit/df71ca834247689fd13f8388cc5d16ff17edff47)
185 |
186 | ### All changes
187 | [`0.2.1...0.3.0`](https://github.com/SAP/connect-openui5/compare/0.2.1...0.3.0)
188 |
--------------------------------------------------------------------------------
/.chglog/RELEASE.tpl.md:
--------------------------------------------------------------------------------
1 | {{ range .Versions }}
2 | {{ range .CommitGroups -}}
3 | ### {{ .Title }}
4 | {{ range .Commits -}}
5 | - {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} [`{{ .Hash.Short }}`]({{ $.Info.RepositoryURL }}/commit/{{ .Hash.Long }})
6 | {{ end }}
7 | {{ end -}}
8 |
9 | {{- if .RevertCommits -}}
10 | ### Reverts
11 | {{ range .RevertCommits -}}
12 | - {{ .Revert.Header }}
13 | {{ end }}
14 | {{ end -}}
15 |
16 | {{- if .NoteGroups -}}
17 | {{ range .NoteGroups -}}
18 | ### {{ .Title }}
19 | {{ range .Notes }}
20 | {{ .Body }}
21 | {{ end }}
22 | {{ end -}}
23 | {{ end -}}
24 |
25 | {{ if .Tag.Previous }}
26 | ### All changes
27 | [`{{ .Tag.Previous.Name }}...{{ .Tag.Name }}`]
28 | {{ end }}
29 |
30 | {{ if .Tag.Previous -}}
31 | [`{{ .Tag.Previous.Name }}...{{ .Tag.Name }}`]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }}
32 | {{ end -}}
33 | {{ end -}}
34 |
--------------------------------------------------------------------------------
/.chglog/config.yml:
--------------------------------------------------------------------------------
1 | style: github
2 | template: CHANGELOG.tpl.md
3 | info:
4 | title: CHANGELOG
5 | repository_url: https://github.com/SAP/connect-openui5
6 | options:
7 | commits:
8 | filters:
9 | Type:
10 | - FEATURE
11 | - FIX
12 | - PERF
13 | - DEPENDENCY
14 | - BREAKING
15 | commit_groups:
16 | title_maps:
17 | FEATURE: Features
18 | FIX: Bug Fixes
19 | PERF: Performance Improvements
20 | DEPENDENCY: Dependency Updates
21 | BREAKING: Breaking Changes
22 | header:
23 | pattern: "^\\[(\\w*)\\]\\s(?:([^\\:]*)\\:\\s)?(.*)$"
24 | pattern_maps:
25 | - Type
26 | - Scope
27 | - Subject
28 | issues:
29 | prefix:
30 | - "#"
31 | notes:
32 | keywords:
33 | - BREAKING CHANGE
34 |
--------------------------------------------------------------------------------
/.chglog/release-config.yml:
--------------------------------------------------------------------------------
1 | style: github
2 | template: RELEASE.tpl.md
3 | info:
4 | repository_url: https://github.com/SAP/connect-openui5
5 | options:
6 | commits:
7 | filters:
8 | Type:
9 | - FEATURE
10 | - FIX
11 | - PERF
12 | - DEPENDENCY
13 | - BREAKING
14 | commit_groups:
15 | title_maps:
16 | FEATURE: Features
17 | FIX: Bug Fixes
18 | PERF: Performance Improvements
19 | DEPENDENCY: Dependency Updates
20 | BREAKING: Breaking Changes
21 | header:
22 | pattern: "^\\[(\\w*)\\]\\s(?:([^\\:]*)\\:\\s)?(.*)$"
23 | pattern_maps:
24 | - Type
25 | - Scope
26 | - Subject
27 | issues:
28 | prefix:
29 | - "#"
30 | notes:
31 | keywords:
32 | - BREAKING CHANGE
33 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # see http://editorconfig.org
2 |
3 | root = true
4 |
5 | [*]
6 | charset = utf-8
7 | indent_style = tab
8 |
9 | [*.{css,html,js,less,txt,json,yml,md}]
10 | trim_trailing_whitespace = true
11 | end_of_line = lf
12 | indent_size = 4
13 | insert_final_newline = true
14 |
15 | [*.{yml,yaml}]
16 | indent_style = space
17 | indent_size = 2
18 |
19 | [*.md]
20 | trim_trailing_whitespace = false
21 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | "env": {
3 | "node": true,
4 | "es6": true
5 | },
6 | "parserOptions": {
7 | "ecmaVersion": 8
8 | },
9 | "extends": ["eslint:recommended", "google"],
10 | "rules": {
11 | "indent": [
12 | "error",
13 | "tab"
14 | ],
15 | "linebreak-style": [
16 | "error",
17 | "unix"
18 | ],
19 | "quotes": [
20 | "error",
21 | "double",
22 | {"allowTemplateLiterals": true}
23 | ],
24 | "semi": [
25 | "error",
26 | "always"
27 | ],
28 | "no-negated-condition": "off",
29 | "require-jsdoc": "off",
30 | "no-mixed-requires": "off",
31 | "max-len": [
32 | "error",
33 | {
34 | "code": 120,
35 | "ignoreUrls": true,
36 | "ignoreRegExpLiterals": true
37 | }
38 | ],
39 | "no-implicit-coercion": [
40 | 2,
41 | {"allow": ["!!"]}
42 | ],
43 | "comma-dangle": "off",
44 | "no-tabs": "off"
45 | },
46 | "root": true
47 | };
48 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto eol=lf
2 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "github-actions"
4 | directory: "/"
5 | schedule:
6 | interval: "weekly"
7 | - package-ecosystem: npm
8 | directory: "/"
9 | schedule:
10 | interval: weekly
11 | day: sunday
12 | time: "10:00"
13 | timezone: Etc/UCT
14 | reviewers:
15 | - matz3
16 | - svbender
17 | versioning-strategy: increase
18 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | name: "CodeQL"
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | # Execute at least once per week to get new findings without active development taking place
10 | schedule:
11 | - cron: '42 15 * * 6'
12 |
13 | jobs:
14 | codeql-analyze:
15 | name: "CodeQL Analyze"
16 | runs-on: ubuntu-latest
17 |
18 | steps:
19 | - name: Checkout repository
20 | uses: actions/checkout@v3.5.2
21 |
22 | # Initializes the CodeQL tools for scanning.
23 | - name: Initialize CodeQL
24 | uses: github/codeql-action/init@v2
25 | with:
26 | languages: 'javascript'
27 | # If you wish to specify custom queries, you can do so here or in a config file.
28 | # By default, queries listed here will override any specified in a config file.
29 | # Prefix the list here with "+" to use these queries and those in the config file.
30 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
31 |
32 | # ℹ️ Command-line programs to run using the OS shell.
33 | # 📚 https://git.io/JvXDl
34 |
35 | - name: Perform CodeQL Analysis
36 | uses: github/codeql-action/analyze@v2
37 |
--------------------------------------------------------------------------------
/.github/workflows/github-ci.yml:
--------------------------------------------------------------------------------
1 | name: GitHub CI
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 | test:
11 | name: General checks, tests and coverage reporting
12 | runs-on: ubuntu-latest
13 | steps:
14 |
15 | - uses: actions/checkout@v3.5.2
16 |
17 | - name: Use Node.js LTS 14.x
18 | uses: actions/setup-node@v3.6.0
19 | with:
20 | node-version: 14.x
21 |
22 | - name: Install dependencies
23 | run: npm ci
24 |
25 | - name: Perform checks and tests
26 | run: npm test
27 |
28 | - name: Send report to Coveralls
29 | uses: coverallsapp/github-action@v2.1.2
30 | with:
31 | github-token: ${{ secrets.GITHUB_TOKEN }}
32 |
33 | test-matrix:
34 | name: Unit tests on Node.js ${{ matrix.node-version }} and ${{ matrix.os }}
35 | strategy:
36 | fail-fast: false
37 | matrix:
38 | node-version: [16]
39 | os: [ubuntu-latest, windows-latest, macOS-latest]
40 | include:
41 | - node-version: 10
42 | os: ubuntu-latest
43 | - node-version: 12
44 | os: ubuntu-latest
45 | - node-version: 14
46 | os: ubuntu-latest
47 | runs-on: ${{ matrix.os }}
48 | steps:
49 |
50 | - uses: actions/checkout@v3.5.2
51 |
52 | - name: Use Node.js ${{ matrix.node-version }}
53 | uses: actions/setup-node@v3.6.0
54 | with:
55 | node-version: ${{ matrix.node-version }}
56 |
57 | - run: npm ci
58 | name: Install dependencies
59 |
60 | - run: npm ls --prod
61 | name: Check for missing / extraneous Dependencies
62 |
63 | - run: npm run unit
64 | name: Run unit tests
65 |
--------------------------------------------------------------------------------
/.github/workflows/reuse-compliance.yml:
--------------------------------------------------------------------------------
1 | name: REUSE
2 |
3 | on:
4 | push:
5 | branches: [ master ]
6 | pull_request:
7 | branches: [ master ]
8 |
9 | jobs:
10 | compliance-check:
11 | name: Compliance Check
12 | runs-on: ubuntu-latest
13 | steps:
14 | - uses: actions/checkout@v3.5.2
15 | - name: Execute REUSE Compliance Check
16 | uses: fsfe/reuse-action@v1.1
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # CI (Azure Pipelines) xUnit test results
21 | test-results.xml
22 |
23 | # IDEs
24 | .vscode/
25 | *.~vsdx
26 | .idea/
27 |
28 | # node-waf configuration
29 | .lock-wscript
30 |
31 | # Compiled binary addons (http://nodejs.org/api/addons.html)
32 | build/Release
33 |
34 | # Dependency directories
35 | node_modules
36 | jspm_packages
37 |
38 | # Optional npm cache directory
39 | .npm
40 |
41 | # Optional eslint cache
42 | .eslintcache
43 |
44 | # Optional REPL history
45 | .node_repl_history
46 |
47 | # Output of 'npm pack'
48 | *.tgz
49 |
50 | # Yarn Integrity file
51 | .yarn-integrity
52 |
53 | # Misc
54 | yarn.lock
55 | .DS_Store
56 |
57 | # Don't include private SSH key for deployment via Travis CI
58 | deploy_key
59 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | # Enforce public npm registry
2 | registry = https://registry.npmjs.org/
3 |
--------------------------------------------------------------------------------
/.reuse/dep5:
--------------------------------------------------------------------------------
1 | Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
2 | Upstream-Name: connect-openui5
3 | Upstream-Contact: SAP OpenUI5
4 | Source: https://github.com/SAP/connect-openui5
5 | Disclaimer: The code in this project may include calls to APIs (“API Calls”) of
6 | SAP or third-party products or services developed outside of this project
7 | (“External Products”).
8 | “APIs” means application programming interfaces, as well as their respective
9 | specifications and implementing code that allows software to communicate with
10 | other software.
11 | API Calls to External Products are not licensed under the open source license
12 | that governs this project. The use of such API Calls and related External
13 | Products are subject to applicable additional agreements with the relevant
14 | provider of the External Products. In no event shall the open source license
15 | that governs this project grant any rights in or to any External Products,or
16 | alter, expand or supersede any terms of the applicable additional agreements.
17 | If you have a valid license agreement with SAP for the use of a particular SAP
18 | External Product, then you may make use of any API Calls included in this
19 | project’s code for that SAP External Product, subject to the terms of such
20 | license agreement. If you do not have a valid license agreement for the use of
21 | a particular SAP External Product, then you may only make use of any API Calls
22 | in this project for that SAP External Product for your internal, non-productive
23 | and non-commercial test and evaluation of such API Calls. Nothing herein grants
24 | you any rights to use or access any SAP External Product, or provide any third
25 | parties the right to use of access any SAP External Product, through API Calls.
26 |
27 | Files: *
28 | Copyright: 2014-2021 SAP SE or an SAP affiliate company and connect-openui5 contributors
29 | License: Apache-2.0
30 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 | All notable changes to this project will be documented in this file.
3 | This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
4 |
5 | A list of unreleased changes can be found [here](https://github.com/SAP/connect-openui5/compare/v0.10.3...HEAD).
6 |
7 |
8 | ## [v0.10.3] - 2022-11-30
9 | ### Dependency Updates
10 | - Bump less-openui5 from 0.11.2 to 0.11.3 [`0619599`](https://github.com/SAP/connect-openui5/commit/061959972e1410628fc081d3c7af75b1f3fe715d)
11 |
12 |
13 |
14 | ## [v0.10.2] - 2021-03-11
15 | ### Dependency Updates
16 | - Bump less-openui5 from 0.10.0 to 0.11.0 ([#110](https://github.com/SAP/connect-openui5/issues/110)) [`4403a88`](https://github.com/SAP/connect-openui5/commit/4403a8841f1971775bbd9d8dabd1a984c604d431)
17 |
18 |
19 |
20 | ## [v0.10.1] - 2021-01-29
21 |
22 |
23 | ## [v0.10.0] - 2020-11-06
24 | ### Breaking Changes
25 | - Require Node.js >= 10 [`8c9f87e`](https://github.com/SAP/connect-openui5/commit/8c9f87e1012bb0c6fbf2dc8e323c7ec11bfda877)
26 |
27 | ### Dependency Updates
28 | - Bump less-openui5 from 0.8.7 to 0.9.0 [`a8cdc7b`](https://github.com/SAP/connect-openui5/commit/a8cdc7bf1c82ba75217db1be50ff502ac3d380df)
29 |
30 | ### BREAKING CHANGE
31 |
32 | Support for older Node.js releases has been dropped.
33 | Only Node.js v10 or higher is supported.
34 |
35 |
36 |
37 | ## [v0.9.1] - 2020-09-10
38 | ### Bug Fixes
39 | - **proxy middleware:** Remove secure, domain, path, samesite from cookies ([#91](https://github.com/SAP/connect-openui5/issues/91)) [`e9784be`](https://github.com/SAP/connect-openui5/commit/e9784be7c40670ccbb153b7e51adccb8603446d8)
40 |
41 |
42 |
43 | ## [v0.9.0] - 2019-11-19
44 | ### Breaking Changes
45 | - **less middleware:** Remove support for 'sourceMap' / 'cleancss' options [`39fa504`](https://github.com/SAP/connect-openui5/commit/39fa504b2cbc6e8273d0712b76b64466b6f8d9ce)
46 |
47 |
48 |
49 | ## [0.8.0] - 2019-10-14
50 | ### Breaking Changes
51 | - Drop support for Node.js < 8.5 [`3aefa16`](https://github.com/SAP/connect-openui5/commit/3aefa16e1e3ecb88214ab8b79d1e2840b26f6dba)
52 |
53 |
54 | [v0.10.3]: https://github.com/SAP/connect-openui5/compare/v0.10.2...v0.10.3
55 | [v0.10.2]: https://github.com/SAP/connect-openui5/compare/v0.10.1...v0.10.2
56 | [v0.10.1]: https://github.com/SAP/connect-openui5/compare/v0.10.0...v0.10.1
57 | [v0.10.0]: https://github.com/SAP/connect-openui5/compare/v0.9.1...v0.10.0
58 | [v0.9.1]: https://github.com/SAP/connect-openui5/compare/v0.9.0...v0.9.1
59 | [v0.9.0]: https://github.com/SAP/connect-openui5/compare/0.8.0...v0.9.0
60 | [0.8.0]: https://github.com/SAP/connect-openui5/compare/0.7.7...0.8.0
61 | ## 0.7.7 - 2019-07-01
62 |
63 | ### Fixes
64 | - proxy middleware
65 | - Removing 'secure' flag of cookies [#50](https://github.com/SAP/connect-openui5/pull/50)
66 |
67 | ### All changes
68 | [`0.7.6...0.7.7`](https://github.com/SAP/connect-openui5/compare/0.7.6...0.7.7)
69 |
70 |
71 | ## 0.7.6 - 2019-03-13
72 |
73 | ### Fixes
74 | - proxy middleware
75 | - Also strip 'secure' cookie flag at the end of the header [#41](https://github.com/SAP/connect-openui5/pull/41)
76 |
77 | ### All changes
78 | [`0.7.5...0.7.6`](https://github.com/SAP/connect-openui5/compare/0.7.5...0.7.6)
79 |
80 |
81 | ## 0.7.5 - 2018-10-09
82 |
83 | ### Other changes
84 | - Update less-openui5@0.6.0 [#27](https://github.com/SAP/connect-openui5/pull/27)
85 |
86 | ### All changes
87 | [`0.7.4...0.7.5`](https://github.com/SAP/connect-openui5/compare/0.7.4...0.7.5)
88 |
89 |
90 | ## 0.7.4 - 2018-05-18
91 |
92 | ### Other changes
93 | - Update less-openui5 to v0.5.3 [#25](https://github.com/SAP/connect-openui5/pull/25)
94 |
95 | ### All changes
96 | [`0.7.3...0.7.4`](https://github.com/SAP/connect-openui5/compare/0.7.3...0.7.4)
97 |
98 |
99 | ## 0.7.3 - 2018-03-12
100 |
101 | ### Other changes
102 | - Update dependencies ([`b8d59ea`](https://github.com/SAP/connect-openui5/commit/b8d59ea8cd1e2db46b5c5f0117f02ed40aa1a097))
103 | - Update copyright years ([`9091d54`](https://github.com/SAP/connect-openui5/commit/9091d5459126a6080a03b5db360c31d9d30c2665))
104 |
105 | ### All changes
106 | [`0.7.2...0.7.3`](https://github.com/SAP/connect-openui5/compare/0.7.2...0.7.3)
107 |
108 |
109 | ## 0.7.2 - 2017-07-18
110 |
111 | ### Fixes
112 | - proxy middleware
113 | - remove "secure" flag from cookies [#18](https://github.com/SAP/connect-openui5/pull/18)
114 |
115 | ### All changes
116 | [`0.7.1...0.7.2`](https://github.com/SAP/connect-openui5/compare/0.7.1...0.7.2)
117 |
118 |
119 | ## 0.7.1 - 2017-06-22
120 |
121 | ### Fixes
122 | - proxy middleware
123 | - fix no_proxy patterns with * wildcard [#16](https://github.com/SAP/connect-openui5/pull/16)
124 |
125 | ### Other changes
126 | - Travis CI: Test Node.js 4, 6 and 8 with npm v5 [#17](https://github.com/SAP/connect-openui5/pull/17)
127 |
128 | ### All changes
129 | [`0.7.0...0.7.1`](https://github.com/SAP/connect-openui5/compare/0.7.0...0.7.1)
130 |
131 |
132 | ## 0.7.0 - 2017-03-23
133 |
134 | ### Breaking changes
135 | - Drop support for Node.js v0.10 [#13](https://github.com/SAP/connect-openui5/pull/13)
136 |
137 | ### Features
138 | - less middleware
139 | - Support theme scopes (Belize Themes) [#15](https://github.com/SAP/connect-openui5/pull/15) (via [SAP/less-openui5#10](https://github.com/SAP/less-openui5/pull/10))
140 |
141 | ### All changes
142 | [`0.6.0...0.7.0`](https://github.com/SAP/connect-openui5/compare/0.6.0...0.7.0)
143 |
144 |
145 | ## 0.6.0 - 2016-04-25
146 |
147 | ### Breaking changes
148 | - less middleware
149 | - Set default of parser option `relativeUrls` to `true` [`4d5fca2 ` via less-openui5@0.2.0](https://github.com/SAP/connect-openui5/commit/4d5fca25954049eec4af53c8bd12c54d6ad020aa) (see [`00d892b `](https://github.com/SAP/less-openui5/commit/00d892b95c8c0401b8a61f1b1709dfc4a68cfa26))
150 |
151 | ### Features
152 | - less middleware
153 | - enable inline theming parameters [`4d5fca2`](https://github.com/SAP/connect-openui5/commit/4d5fca25954049eec4af53c8bd12c54d6ad020aa)
154 |
155 | ### All changes
156 | [`0.5.0...0.6.0`](https://github.com/SAP/connect-openui5/compare/0.5.0...0.6.0)
157 |
158 |
159 | ## 0.5.0 - 2016-01-20
160 |
161 | ### Features
162 | - proxy middleware
163 | - Add support for modifying the remote location via environment variable [`46c1e56`](https://github.com/SAP/connect-openui5/commit/46c1e56db46357fee59ee072e0c82516d5c17e9e)
164 |
165 | ### All changes
166 | [`0.4.1...0.5.0`](https://github.com/SAP/connect-openui5/compare/0.4.1...0.5.0)
167 |
168 |
169 | ## 0.4.1 - 2015-09-04
170 |
171 | ### Fixes
172 | - less middleware
173 | - Extend default options rather than assign with provided options [`5ae50cd`](https://github.com/SAP/connect-openui5/commit/5ae50cd753ef5e2a3ba2807a70877ef79b6ce433)
174 |
175 | ### All changes
176 | [`0.4.0...0.4.1`](https://github.com/SAP/connect-openui5/compare/0.4.0...0.4.1)
177 |
178 |
179 | ## 0.4.0 - 2015-01-12
180 |
181 | ### Features
182 | - proxy middleware
183 | - allow passing options for [http-proxy](https://github.com/nodejitsu/node-http-proxy#options) [`6ab9920`](https://github.com/SAP/connect-openui5/commit/6ab99201d5d2439ba55017ec8211b4dd8e5ed2a9)
184 |
185 | ### All changes
186 | [`0.3.0...0.4.0`](https://github.com/SAP/connect-openui5/compare/0.3.0...0.4.0)
187 |
188 |
189 | ## 0.3.0 - 2014-11-17
190 |
191 | ### Breaking changes
192 | - context middleware
193 | - removed (not needed anymore) [`7977fde`](https://github.com/SAP/connect-openui5/commit/7977fdeaf53a6caf9f4ef4f410bd01e13927be3c)
194 | - less middleware
195 | - changed `options` argument to [less-openui5](https://github.com/SAP/less-openui5) options [`bf6d596`](https://github.com/SAP/connect-openui5/commit/bf6d596d67c5915408dc6287d15baa6a5e311c3e)
196 |
197 | ### Fixes
198 | - proxy middleware
199 | - now respects the local proxy configuration (environment variables `HTTP_PROXY`, `HTTPS_PROXY`, `NO_PROXY`) when making requests [`483e137`](https://github.com/SAP/connect-openui5/commit/483e1377caa0e90e3f4be9cc8ca91b01b4581103)
200 | - less middleware
201 | - next should not be called after ending the response [`df71ca8`](https://github.com/SAP/connect-openui5/commit/df71ca834247689fd13f8388cc5d16ff17edff47)
202 |
203 | ### All changes
204 | [`0.2.1...0.3.0`](https://github.com/SAP/connect-openui5/compare/0.2.1...0.3.0)
205 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to connect-openui5
2 |
3 | In general the contributing guidelines of OpenUI5 also apply to this project. They can be found here:
4 | https://github.com/SAP/openui5/blob/master/CONTRIBUTING.md
5 |
6 | Some parts might not be relevant for this project (e.g. the browser-specific requirements like jQuery, CSS and accessibility in the "Contribution Content Guidelines") and the contribution process is easier (pull requests will be merged directly on GitHub).
7 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright 2021 SAP SE or an SAP affiliate company.
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/LICENSES/Apache-2.0.txt:
--------------------------------------------------------------------------------
1 | Apache License
2 |
3 | Version 2.0, January 2004
4 |
5 | http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION,
6 | AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 |
11 |
12 | "License" shall mean the terms and conditions for use, reproduction, and distribution
13 | as defined by Sections 1 through 9 of this document.
14 |
15 |
16 |
17 | "Licensor" shall mean the copyright owner or entity authorized by the copyright
18 | owner that is granting the License.
19 |
20 |
21 |
22 | "Legal Entity" shall mean the union of the acting entity and all other entities
23 | that control, are controlled by, or are under common control with that entity.
24 | For the purposes of this definition, "control" means (i) the power, direct
25 | or indirect, to cause the direction or management of such entity, whether
26 | by contract or otherwise, or (ii) ownership of fifty percent (50%) or more
27 | of the outstanding shares, or (iii) beneficial ownership of such entity.
28 |
29 |
30 |
31 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions
32 | granted by this License.
33 |
34 |
35 |
36 | "Source" form shall mean the preferred form for making modifications, including
37 | but not limited to software source code, documentation source, and configuration
38 | files.
39 |
40 |
41 |
42 | "Object" form shall mean any form resulting from mechanical transformation
43 | or translation of a Source form, including but not limited to compiled object
44 | code, generated documentation, and conversions to other media types.
45 |
46 |
47 |
48 | "Work" shall mean the work of authorship, whether in Source or Object form,
49 | made available under the License, as indicated by a copyright notice that
50 | is included in or attached to the work (an example is provided in the Appendix
51 | below).
52 |
53 |
54 |
55 | "Derivative Works" shall mean any work, whether in Source or Object form,
56 | that is based on (or derived from) the Work and for which the editorial revisions,
57 | annotations, elaborations, or other modifications represent, as a whole, an
58 | original work of authorship. For the purposes of this License, Derivative
59 | Works shall not include works that remain separable from, or merely link (or
60 | bind by name) to the interfaces of, the Work and Derivative Works thereof.
61 |
62 |
63 |
64 | "Contribution" shall mean any work of authorship, including the original version
65 | of the Work and any modifications or additions to that Work or Derivative
66 | Works thereof, that is intentionally submitted to Licensor for inclusion in
67 | the Work by the copyright owner or by an individual or Legal Entity authorized
68 | to submit on behalf of the copyright owner. For the purposes of this definition,
69 | "submitted" means any form of electronic, verbal, or written communication
70 | sent to the Licensor or its representatives, including but not limited to
71 | communication on electronic mailing lists, source code control systems, and
72 | issue tracking systems that are managed by, or on behalf of, the Licensor
73 | for the purpose of discussing and improving the Work, but excluding communication
74 | that is conspicuously marked or otherwise designated in writing by the copyright
75 | owner as "Not a Contribution."
76 |
77 |
78 |
79 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf
80 | of whom a Contribution has been received by Licensor and subsequently incorporated
81 | within the Work.
82 |
83 | 2. Grant of Copyright License. Subject to the terms and conditions of this
84 | License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
85 | no-charge, royalty-free, irrevocable copyright license to reproduce, prepare
86 | Derivative Works of, publicly display, publicly perform, sublicense, and distribute
87 | the Work and such Derivative Works in Source or Object form.
88 |
89 | 3. Grant of Patent License. Subject to the terms and conditions of this License,
90 | each Contributor hereby grants to You a perpetual, worldwide, non-exclusive,
91 | no-charge, royalty-free, irrevocable (except as stated in this section) patent
92 | license to make, have made, use, offer to sell, sell, import, and otherwise
93 | transfer the Work, where such license applies only to those patent claims
94 | licensable by such Contributor that are necessarily infringed by their Contribution(s)
95 | alone or by combination of their Contribution(s) with the Work to which such
96 | Contribution(s) was submitted. If You institute patent litigation against
97 | any entity (including a cross-claim or counterclaim in a lawsuit) alleging
98 | that the Work or a Contribution incorporated within the Work constitutes direct
99 | or contributory patent infringement, then any patent licenses granted to You
100 | under this License for that Work shall terminate as of the date such litigation
101 | is filed.
102 |
103 | 4. Redistribution. You may reproduce and distribute copies of the Work or
104 | Derivative Works thereof in any medium, with or without modifications, and
105 | in Source or Object form, provided that You meet the following conditions:
106 |
107 | (a) You must give any other recipients of the Work or Derivative Works a copy
108 | of this License; and
109 |
110 | (b) You must cause any modified files to carry prominent notices stating that
111 | You changed the files; and
112 |
113 | (c) You must retain, in the Source form of any Derivative Works that You distribute,
114 | all copyright, patent, trademark, and attribution notices from the Source
115 | form of the Work, excluding those notices that do not pertain to any part
116 | of the Derivative Works; and
117 |
118 | (d) If the Work includes a "NOTICE" text file as part of its distribution,
119 | then any Derivative Works that You distribute must include a readable copy
120 | of the attribution notices contained within such NOTICE file, excluding those
121 | notices that do not pertain to any part of the Derivative Works, in at least
122 | one of the following places: within a NOTICE text file distributed as part
123 | of the Derivative Works; within the Source form or documentation, if provided
124 | along with the Derivative Works; or, within a display generated by the Derivative
125 | Works, if and wherever such third-party notices normally appear. The contents
126 | of the NOTICE file are for informational purposes only and do not modify the
127 | License. You may add Your own attribution notices within Derivative Works
128 | that You distribute, alongside or as an addendum to the NOTICE text from the
129 | Work, provided that such additional attribution notices cannot be construed
130 | as modifying the License.
131 |
132 | You may add Your own copyright statement to Your modifications and may provide
133 | additional or different license terms and conditions for use, reproduction,
134 | or distribution of Your modifications, or for any such Derivative Works as
135 | a whole, provided Your use, reproduction, and distribution of the Work otherwise
136 | complies with the conditions stated in this License.
137 |
138 | 5. Submission of Contributions. Unless You explicitly state otherwise, any
139 | Contribution intentionally submitted for inclusion in the Work by You to the
140 | Licensor shall be under the terms and conditions of this License, without
141 | any additional terms or conditions. Notwithstanding the above, nothing herein
142 | shall supersede or modify the terms of any separate license agreement you
143 | may have executed with Licensor regarding such Contributions.
144 |
145 | 6. Trademarks. This License does not grant permission to use the trade names,
146 | trademarks, service marks, or product names of the Licensor, except as required
147 | for reasonable and customary use in describing the origin of the Work and
148 | reproducing the content of the NOTICE file.
149 |
150 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to
151 | in writing, Licensor provides the Work (and each Contributor provides its
152 | Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
153 | KIND, either express or implied, including, without limitation, any warranties
154 | or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR
155 | A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness
156 | of using or redistributing the Work and assume any risks associated with Your
157 | exercise of permissions under this License.
158 |
159 | 8. Limitation of Liability. In no event and under no legal theory, whether
160 | in tort (including negligence), contract, or otherwise, unless required by
161 | applicable law (such as deliberate and grossly negligent acts) or agreed to
162 | in writing, shall any Contributor be liable to You for damages, including
163 | any direct, indirect, special, incidental, or consequential damages of any
164 | character arising as a result of this License or out of the use or inability
165 | to use the Work (including but not limited to damages for loss of goodwill,
166 | work stoppage, computer failure or malfunction, or any and all other commercial
167 | damages or losses), even if such Contributor has been advised of the possibility
168 | of such damages.
169 |
170 | 9. Accepting Warranty or Additional Liability. While redistributing the Work
171 | or Derivative Works thereof, You may choose to offer, and charge a fee for,
172 | acceptance of support, warranty, indemnity, or other liability obligations
173 | and/or rights consistent with this License. However, in accepting such obligations,
174 | You may act only on Your own behalf and on Your sole responsibility, not on
175 | behalf of any other Contributor, and only if You agree to indemnify, defend,
176 | and hold each Contributor harmless for any liability incurred by, or claims
177 | asserted against, such Contributor by reason of your accepting any such warranty
178 | or additional liability. END OF TERMS AND CONDITIONS
179 |
180 | APPENDIX: How to apply the Apache License to your work.
181 |
182 | To apply the Apache License to your work, attach the following boilerplate
183 | notice, with the fields enclosed by brackets "[]" replaced with your own identifying
184 | information. (Don't include the brackets!) The text should be enclosed in
185 | the appropriate comment syntax for the file format. We also recommend that
186 | a file or class name and description of purpose be included on the same "printed
187 | page" as the copyright notice for easier identification within third-party
188 | archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 |
194 | you may not use this file except in compliance with the License.
195 |
196 | You may obtain a copy of the License at
197 |
198 | http://www.apache.org/licenses/LICENSE-2.0
199 |
200 | Unless required by applicable law or agreed to in writing, software
201 |
202 | distributed under the License is distributed on an "AS IS" BASIS,
203 |
204 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
205 |
206 | See the License for the specific language governing permissions and
207 |
208 | limitations under the License.
209 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | [](https://api.reuse.software/info/github.com/SAP/connect-openui5)
4 | [](https://travis-ci.org/SAP/connect-openui5)
5 | [](https://www.npmjs.org/package/connect-openui5)
6 |
7 | # DEPRECATED
8 |
9 | **⚠️ This project has been deprecated in favor of [UI5 Tooling](https://sap.github.io/ui5-tooling/) and proxy solutions that are available in the form of [custom middleware extensions from the UI5 community](https://bestofui5.org/#/packages?tokens=proxy:tag).**
10 |
11 | # connect-openui5
12 |
13 | > [Connect](https://github.com/senchalabs/connect) middleware for OpenUI5.
14 |
15 | Looking for a grunt task to run a web server with this middleware? Check out [grunt-openui5](https://github.com/SAP/grunt-openui5)!
16 |
17 | ## Install
18 |
19 | ```
20 | npm install connect-openui5
21 | ```
22 |
23 | ## Usage
24 |
25 | ```js
26 | var connect = require('connect');
27 | var http = require('http');
28 | var app = connect();
29 |
30 | var middleware = require('connect-openui5');
31 |
32 | // Compiles LESS themes on the fly
33 | app.use(middleware.less({
34 | rootPaths: [ 'path/to/theme/resources' ]
35 | }));
36 |
37 | // Makes sure that properties files will be served with "Content-Type: text/plain; charset=ISO-8859-1"
38 | app.use(middleware.properties());
39 |
40 | // Provides a generic proxy to consume resources from other origins without causing CORS issues
41 | // URL-Format: /{http|https}/{host}/{path}
42 | app.use('/proxy', middleware.proxy());
43 |
44 | // Provide discovery service (used in OpenUI5 testsuite)
45 | app.use('/discovery', middleware.discovery({
46 | appresources: [ 'path/to/app-resources' ],
47 | resources: [ 'path/to/resources' ],
48 | testresources: [ 'path/to/test-resources' ]
49 | }));
50 |
51 | // create node.js http server and listen on port
52 | http.createServer(app).listen(3000);
53 |
54 | ```
55 |
56 | ## less
57 |
58 | Compiles LESS themes on the fly. The results will be cached and only re-compiled if a file has changed.
59 |
60 | The following files will be handled
61 | - library.css
62 | - library-RTL.css
63 | - library-parameters.json
64 |
65 | The `library.source.less` file in the same directory will be used for compilation.
66 |
67 | ### API
68 |
69 | #### less(options)
70 |
71 | ##### options
72 |
73 | Type: `object`
74 |
75 | Options for [less-openui5](https://github.com/SAP/less-openui5#options).
76 |
77 | ## properties
78 |
79 | This middleware function ensures that properties files will be served with "Content-Type: text/plain; charset=ISO-8859-1".
80 |
81 | ## proxy
82 |
83 | Provides a generic proxy to consume resources from other origins without causing CORS issues.
84 |
85 | URL-Format `/{http|https}/{host}/{path}`
86 |
87 | ### remote location
88 |
89 | The environment variable REMOTE_LOCATION allows setting a remote location.
90 |
91 | Usage:
92 | Use a URL without the pattern `/{http|https}/{host}` and the proxy will use the environment variable REMOTE_LOCATION
93 | to determine host and additional path information. Also query parameters can be added.
94 |
95 | Sample:
96 |
97 | URL-Format: `/foo/bar?test=1234`
98 |
99 | REMOTE_LOCATION: `https://remotehost:1234/rfoo/rbar?rtest=1234`
100 |
101 | Composed URL send to remote host: `/rfoo/rbar/foo/bar?rtest=1234&test=1234`.
102 |
103 | The similar URL without using REMOTE_LOCATION would be `/https/remotehost:1234/rfoo/rbar/foo/bar?rtest=1234&test=1234`
104 |
105 | ### API
106 |
107 | #### proxy(options)
108 |
109 | ##### options
110 |
111 | Type: `object`
112 | Default: `{}`
113 |
114 | Options for [http-proxy](https://github.com/nodejitsu/node-http-proxy#options).
115 |
116 | ## discovery
117 |
118 | Provides a resource discovery service (consumed in the [OpenUI5 testsuite](https://github.com/SAP/openui5/tree/master/src/sap.ui.core/test/testsuite)).
119 |
120 | ### API
121 |
122 | #### discovery(options)
123 |
124 | ##### options
125 |
126 | ###### appresources
127 |
128 | Type: `array` of `string`
129 |
130 | Application resource folder(s), see `/app_pages`.
131 |
132 | ###### resources
133 |
134 | Type: `array` of `string`
135 |
136 | OpenUI5 library resource folder(s), see `/all_libs`.
137 |
138 | ###### testresources
139 |
140 | Type: `array` of `string`
141 |
142 | OpenUI5 library test-resource folder(s), see `/all_tests`.
143 |
144 | ### Endpoints
145 |
146 | #### /app_pages
147 |
148 | Returns all `*.html`/`*.htm` pages located in the `appresources` folder(s).
149 |
150 | ```json
151 | {
152 | "app_pages": [
153 | {
154 | "entry": "myApp.html"
155 | }
156 | ]
157 | }
158 | ```
159 |
160 | #### /all_libs
161 |
162 | Returns all libraries located in the `resources` folder(s). They will be identified by a `.library`.
163 |
164 | ```json
165 | {
166 | "all_libs": [
167 | {
168 | "entry": "my/ui/lib"
169 | }
170 | ]
171 | }
172 | ```
173 |
174 | #### /all_tests
175 |
176 | Returns all `*.html`/`*.htm` pages located in the `testresources` folder(s).
177 |
178 | ```json
179 | {
180 | "all_tests": [
181 | {
182 | "lib": "my.ui.lib",
183 | "name": "qunit/MyControl.qunit.html",
184 | "url": "test-resources/my/ui/lib/qunit/MyControl.qunit.html"
185 | }
186 | ]
187 | }
188 | ```
189 |
190 | ## Contributing
191 |
192 | See [CONTRIBUTING.md](CONTRIBUTING.md).
193 |
194 | ## Release History
195 |
196 | See [CHANGELOG.md](CHANGELOG.md).
197 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Reporting Security Issues
2 |
3 | We take security issues in our projects seriously. We appreciate your efforts to responsibly disclose your findings.
4 |
5 | Please do not report security issues directly on GitHub but using one of the channels listed below. This allows us to provide a fix before an issue can be exploited.
6 |
7 | - **Researchers/Non-SAP Customers:** Please consult SAPs [disclosure guidelines](https://wiki.scn.sap.com/wiki/display/PSR/Disclosure+Guidelines+for+SAP+Security+Advisories) and send the related information in a PGP encrypted e-mail to secure@sap.com. Find the public PGP key [here](https://www.sap.com/dmc/policies/pgp/keyblock.txt).
8 | - **SAP Customers:** If the security issue is not covered by a published security note, please report it by creating a customer message at https://launchpad.support.sap.com.
9 |
10 | Please also refer to the general [SAP security information page](https://www.sap.com/about/trust-center/security/incident-management.html).
11 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | module.exports = {
4 |
5 | discovery: require("./lib/discovery"),
6 | less: require("./lib/less"),
7 | properties: require("./lib/properties"),
8 | proxy: require("./lib/proxy")
9 |
10 | };
11 |
--------------------------------------------------------------------------------
/lib/discovery.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const async = require("async");
4 | const glob = require("glob");
5 |
6 | const librariesPattern = /([A-Z0-9._%+-/]+)\/[A-Z0-9._]*\.library$/i;
7 | const testPagesPattern = /(([A-Z0-9._%+-]+\/)+([A-Z_0-9-\\.]+)\.(html|htm))$/i;
8 | const urlPattern = /\/(app_pages|all_libs|all_tests)(?:[?#].*)?$/;
9 |
10 | function eachGlobbedFile(folders, globPatterns, eachCallback, finishedCallback) {
11 | if (typeof globPatterns === "string") {
12 | globPatterns = [globPatterns];
13 | }
14 | async.eachSeries(folders, function(folder, folderDone) {
15 | async.eachSeries(globPatterns, function(globPattern, globDone) {
16 | glob(globPattern, {cwd: folder}, function(err, files) {
17 | if (err) {
18 | globDone(err);
19 | }
20 | files.forEach(eachCallback);
21 | globDone();
22 | });
23 | }, folderDone);
24 | }, finishedCallback);
25 | }
26 |
27 | module.exports = function(options) {
28 | return function discoveryMiddleware(req, res, next) {
29 | const parts = urlPattern.exec(req.url);
30 | const type = parts && parts[1];
31 | if (!type) {
32 | next();
33 | return;
34 | }
35 |
36 | const response = [];
37 |
38 | function sendResponse() {
39 | const responseData = {};
40 | responseData[type] = response;
41 | res.writeHead(200, {
42 | "Content-Type": "application/json"
43 | });
44 | res.end(JSON.stringify(responseData));
45 | }
46 |
47 | if (type === "app_pages") {
48 | eachGlobbedFile(options.appresources, "**/*.{html,htm}", function(file) {
49 | response.push({
50 | entry: file
51 | });
52 | }, sendResponse);
53 | } else if (type === "all_libs") {
54 | eachGlobbedFile(options.resources, ["**/.library", "**/*.library"], function(file) {
55 | const match = librariesPattern.exec(file);
56 | if (match) {
57 | response.push({
58 | entry: match[1]
59 | });
60 | }
61 | }, sendResponse);
62 | } else if (type === "all_tests") {
63 | const mLibs = {};
64 |
65 | async.series([
66 | function(done) {
67 | eachGlobbedFile(options.resources, ["**/.library", "**/*.library"], function(file) {
68 | const match = librariesPattern.exec(file);
69 | if (match) {
70 | const lib = match[1];
71 | mLibs[lib] = lib.replace(/\//g, ".");
72 | }
73 | }, done);
74 | },
75 | function(done) {
76 | eachGlobbedFile(options.testresources, "**/*.{html,htm}", function(file) {
77 | if (testPagesPattern.test(file)) {
78 | Object.keys(mLibs).forEach(function(lib) {
79 | if (file.indexOf(lib + "/") === 0) {
80 | response.push({
81 | lib: mLibs[lib],
82 | name: file.substr(lib.length + 1),
83 | url: "../" + file
84 | });
85 | }
86 | });
87 | }
88 | }, done);
89 | }
90 | ], sendResponse);
91 | }
92 | };
93 | };
94 |
--------------------------------------------------------------------------------
/lib/less.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const url = require("url");
4 | const path = require("path");
5 | const extend = require("extend");
6 | const less = require("less-openui5");
7 |
8 |
9 | const themeFilesPattern = /^\/(.*)\/themes\/(.*)\/library(\.css|-RTL\.css|-parameters\.json)$/;
10 |
11 | module.exports = function(options) {
12 | const builder = new less.Builder();
13 |
14 | return function lessMiddleware(req, res, next) {
15 | // handle only GET / HEAD requests
16 | if (!/^(GET|HEAD)$/i.test(req.method)) {
17 | next();
18 | return;
19 | }
20 |
21 | const pathname = url.parse(req.url).pathname;
22 |
23 | /*
24 | groups (array index):
25 | 1 => library name
26 | 2 => theme name
27 | 3 => theme suffix
28 | */
29 | const pathInfo = themeFilesPattern.exec(pathname);
30 | if (!pathInfo) {
31 | next();
32 | return;
33 | }
34 |
35 | const dirname = path.dirname(pathname);
36 | const lessInputPath = dirname + "/library.source.less";
37 |
38 | // Only compile rtl version if requested
39 | const rtl = pathInfo[3] === "-RTL.css";
40 |
41 | const lessOptions = extend(true, {
42 | lessInputPath: lessInputPath,
43 | library: {
44 | name: pathInfo[1].replace(/\//g, ".")
45 | },
46 | rtl: rtl
47 | }, options);
48 |
49 | builder.build(lessOptions).then(function(result) {
50 | // serve result
51 | switch (pathInfo[3]) {
52 | case ".css":
53 | res.setHeader("Content-Type", "text/css");
54 | res.write(result.css);
55 | break;
56 | case "-RTL.css":
57 | res.setHeader("Content-Type", "text/css");
58 | res.write(result.cssRtl);
59 | break;
60 | case "-parameters.json":
61 | res.setHeader("Content-Type", "application/json");
62 | res.write(JSON.stringify(result.variables, null, "\t"));
63 | break;
64 | // no default
65 | }
66 | res.end();
67 | }, function(err) {
68 | if (err) {
69 | next(err);
70 | return;
71 | }
72 | });
73 | };
74 | };
75 |
--------------------------------------------------------------------------------
/lib/properties.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const url = require("url");
4 |
5 | module.exports = function() {
6 | const rProperties = /\.properties$/;
7 | return function propertiesMiddleware(req, res, next) {
8 | // ensure that *.properties files will be served as text/plain; charset=ISO-8859-1
9 | const sUrl = url.parse(req.url).pathname;
10 | if (rProperties.test(sUrl)) {
11 | res.setHeader("Content-Type", "text/plain; charset=ISO-8859-1");
12 | }
13 | next();
14 | };
15 | };
16 |
--------------------------------------------------------------------------------
/lib/proxy-rewrite-cookies.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const serialize = require("cookie").serialize;
4 | const parse = require("set-cookie-parser").parse;
5 | function noop($) {
6 | return $;
7 | }
8 |
9 | module.exports = function(cookies) {
10 | // Can't use cookie.parse as it only parses 'Cookie' headers, not 'Set-Cookie'
11 | // See https://github.com/jshttp/cookie/issues/58
12 | return parse(cookies, {
13 | // Do not decode as we don't want to change the value
14 | decodeValues: false,
15 | map: false // ensure to return array
16 | }).map(function(cookie) {
17 | return serialize(cookie.name, cookie.value, {
18 | // Do not pass "secure", "domain", "path", "sameSite" to remove them from the cookie
19 | expires: cookie.expires,
20 | maxAge: cookie.maxAge,
21 | httpOnly: cookie.httpOnly,
22 |
23 | // As we didn't decode, we should also not encode the value
24 | // Encoding can't be disabled so just providing a "noop" function
25 | // that returns the given value
26 | encode: noop
27 | });
28 | });
29 | };
30 |
--------------------------------------------------------------------------------
/lib/proxy.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | const url = require("url");
4 | const httpProxy = require("http-proxy");
5 | const rewriteCookies = require("./proxy-rewrite-cookies");
6 |
7 | const env = {
8 | noProxy: process.env.NO_PROXY || process.env.no_proxy,
9 | httpProxy: process.env.HTTP_PROXY || process.env.http_proxy,
10 | httpsProxy: process.env.HTTPS_PROXY || process.env.https_proxy,
11 | remoteLocation: process.env.REMOTE_LOCATION || process.env.remote_location
12 | };
13 |
14 | // inspired by https://github.com/request/request/blob/33cd9e297a00c5540e55778a24a706effc35434c/request.js#L169
15 | function getProxyUri(uri) {
16 | if (uri.protocol === "https:" && env.httpsProxy || uri.protocol === "http:" && env.httpProxy) {
17 | if (env.noProxy) {
18 | const canonicalHost = uri.host.replace(/^\.*/, ".");
19 | const port = uri.port || (uri.protocol === "https:" ? "443" : "80");
20 |
21 | const patterns = env.noProxy.split(",");
22 | for (let i = patterns.length - 1; i >= 0; i--) {
23 | let pattern = patterns[i].trim().toLowerCase();
24 |
25 | // don't use a proxy at all
26 | if (pattern === "*") {
27 | return null;
28 | }
29 |
30 | // Remove leading * and make sure to have exact one leading dot (.)
31 | pattern = pattern.replace(/^[*]+/, "").replace(/^\.*/, ".");
32 |
33 | // add port if no specified
34 | if (pattern.indexOf(":") === -1) {
35 | pattern += ":" + port;
36 | }
37 |
38 | // if host ends with pattern, no proxy should be used
39 | if (canonicalHost.indexOf(pattern) === canonicalHost.length - pattern.length) {
40 | return null;
41 | }
42 | }
43 | }
44 |
45 | if (uri.protocol === "https:" && env.httpsProxy) {
46 | return env.httpsProxy;
47 | } else if (uri.protocol === "http:" && env.httpProxy) {
48 | return env.httpProxy;
49 | }
50 | }
51 |
52 | return null;
53 | }
54 |
55 |
56 | function createUri(uriParam, pRemoteUri) {
57 | // parse the request url
58 | const urlPattern = /^\/(http|https)\/(.*)/;
59 | const parts = urlPattern.exec(uriParam);
60 | if (parts) {
61 | // parse target url
62 | return url.parse(parts[1] + "://" + parts[2]);
63 | }
64 |
65 | // if no absolute url is provided, check for REMOTE_LOCATION (which itself must be an absolute url)
66 | if (!pRemoteUri) {
67 | return undefined;
68 | }
69 |
70 | const remoteUri = url.parse(pRemoteUri);
71 | const uri = url.parse(uriParam); // actual url
72 |
73 | // mix both uri objects
74 | if (uri.pathname) {
75 | if ( "/" == remoteUri.pathname.substring(remoteUri.pathname.length-1)) {
76 | // remoteUri.pathname ends with /
77 | remoteUri.pathname = remoteUri.pathname + uri.pathname.substring(1);
78 | } else {
79 | remoteUri.pathname = remoteUri.pathname + uri.pathname;
80 | }
81 | }
82 |
83 | if (uri.query) {
84 | if (remoteUri.query) {
85 | remoteUri.query = remoteUri.query + (remoteUri.query.length > 0 ? "&" : "") + uri.query;
86 | } else {
87 | remoteUri.query = uri.query;
88 | }
89 | }
90 |
91 | return remoteUri;
92 | }
93 |
94 | function buildRequestUrl(uri) {
95 | let ret = uri.pathname;
96 | if (uri.query ) {
97 | ret += "?" + uri.query;
98 | }
99 | return ret;
100 | }
101 |
102 | module.exports = function(options) {
103 | const proxy = httpProxy.createProxyServer(options || {});
104 |
105 | return function(req, res, next) {
106 | const uri = createUri(req.url, env.remoteLocation);
107 | if (!uri || !uri.host) {
108 | next();
109 | return;
110 | }
111 |
112 | // change original request url to target url
113 | req.url = buildRequestUrl(uri);
114 |
115 | // change original host to target host
116 | req.headers.host = uri.host;
117 |
118 | // overwrite response headers
119 | res.orgWriteHead = res.writeHead;
120 | res.writeHead = function(...args) {
121 | const cookies = rewriteCookies(res.getHeader("set-cookie"));
122 | res.setHeader("set-cookie", cookies);
123 | // call original writeHead function
124 | res.orgWriteHead(...args);
125 | };
126 |
127 | // get proxy for uri (if defined in env vars)
128 | const targetUri = getProxyUri(uri) || uri.protocol + "//" + uri.host;
129 |
130 | // proxy the request
131 | proxy.proxyRequest(req, res, {
132 | target: targetUri
133 | }, function(err) {
134 | if (err) {
135 | next(err);
136 | }
137 | });
138 | };
139 | };
140 |
141 | // For testing
142 | module.exports._createUri = createUri;
143 | module.exports._buildRequestUrl = buildRequestUrl;
144 | module.exports._env = env;
145 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "connect-openui5",
3 | "version": "0.10.3",
4 | "description": "Connect middleware for OpenUI5",
5 | "author": {
6 | "name": "SAP SE",
7 | "email": "openui5@sap.com",
8 | "url": "https://www.sap.com"
9 | },
10 | "license": "Apache-2.0",
11 | "keywords": [
12 | "openui5",
13 | "sapui5",
14 | "ui5",
15 | "connect",
16 | "server",
17 | "middleware"
18 | ],
19 | "main": "index.js",
20 | "engines": {
21 | "node": ">= 10",
22 | "npm": ">= 5"
23 | },
24 | "scripts": {
25 | "lint": "eslint ./",
26 | "unit": "mocha test/*.js",
27 | "coverage": "nyc npm run unit",
28 | "test": "npm run lint && npm run coverage && npm run depcheck",
29 | "preversion": "npm test",
30 | "version": "git-chglog --next-tag v$npm_package_version -o CHANGELOG.md 0.8.0.. && git add CHANGELOG.md",
31 | "postversion": "git push --follow-tags",
32 | "release-note": "git-chglog -c .chglog/release-config.yml v$npm_package_version",
33 | "depcheck": "depcheck"
34 | },
35 | "files": [
36 | "index.js",
37 | "lib",
38 | "LICENSE.txt",
39 | "LICENSES/**",
40 | ".reuse/**"
41 | ],
42 | "nyc": {
43 | "reporter": [
44 | "lcov",
45 | "text",
46 | "text-summary"
47 | ],
48 | "exclude": [
49 | "coverage/**",
50 | "test/**",
51 | ".eslintrc.js"
52 | ],
53 | "check-coverage": true,
54 | "statements": 75,
55 | "branches": 55,
56 | "functions": 90,
57 | "lines": 80,
58 | "watermarks": {
59 | "statements": [
60 | 70,
61 | 90
62 | ],
63 | "branches": [
64 | 70,
65 | 90
66 | ],
67 | "functions": [
68 | 70,
69 | 90
70 | ],
71 | "lines": [
72 | 70,
73 | 90
74 | ]
75 | },
76 | "cache": true,
77 | "all": true
78 | },
79 | "repository": {
80 | "type": "git",
81 | "url": "git@github.com:SAP/connect-openui5.git"
82 | },
83 | "dependencies": {
84 | "async": "^3.2.4",
85 | "cookie": "^0.4.2",
86 | "extend": "^3.0.2",
87 | "glob": "^7.2.3",
88 | "http-proxy": "^1.18.1",
89 | "less-openui5": "^0.11.6",
90 | "set-cookie-parser": "^2.6.0"
91 | },
92 | "devDependencies": {
93 | "connect": "^3.7.0",
94 | "depcheck": "^1.4.3",
95 | "eslint": "^7.32.0",
96 | "eslint-config-google": "^0.14.0",
97 | "mocha": "^8.4.0",
98 | "nyc": "^15.1.0",
99 | "serve-static": "^1.15.0"
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/test/discovery_test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | "use strict";
3 |
4 | const http = require("http");
5 | const assert = require("assert");
6 | const connect = require("connect");
7 | const discovery = require("../").discovery;
8 |
9 | describe("discovery middleware", function() {
10 | it("should provide \"app_pages\" json response", function(done) {
11 | const app = connect();
12 |
13 | app.use("/discovery", discovery({
14 | appresources: [
15 | "test/fixtures/discovery/app-resources1",
16 | "test/fixtures/discovery/app-resources2"
17 | ]
18 | }));
19 |
20 | const server = http.createServer(app).listen(8080);
21 |
22 | http.get("http://localhost:8080/discovery/app_pages", function(res) {
23 | let responseData = "";
24 | res.on("data", function(data) {
25 | responseData += data;
26 | });
27 | res.on("end", function() {
28 | assert.equal(responseData, JSON.stringify({
29 | "app_pages": [
30 | {
31 | entry: "index.html"
32 | },
33 | {
34 | entry: "foo/bar.htm"
35 | }
36 | ]
37 | }));
38 |
39 | server.close();
40 | done();
41 | });
42 | });
43 | });
44 |
45 | it("should provide \"all_libs\" json response", function(done) {
46 | const app = connect();
47 |
48 | app.use("/discovery", discovery({
49 | resources: [
50 | "test/fixtures/discovery/resources1",
51 | "test/fixtures/discovery/resources2",
52 | "test/fixtures/discovery/resources3"
53 | ]
54 | }));
55 |
56 | const server = http.createServer(app).listen(8080);
57 |
58 | http.get("http://localhost:8080/discovery/all_libs", function(res) {
59 | let responseData = "";
60 | res.on("data", function(data) {
61 | responseData += data;
62 | });
63 | res.on("end", function() {
64 | assert.equal(responseData, JSON.stringify({
65 | "all_libs": [
66 | {
67 | entry: "my/ui/lib"
68 | },
69 | {
70 | entry: "my/legacy/ui/lib"
71 | },
72 | {
73 | entry: "my/ui/l"
74 | }
75 | ]
76 | }));
77 |
78 | server.close();
79 | done();
80 | });
81 | });
82 | });
83 |
84 | it("should provide \"all_tests\" json response", function(done) {
85 | const app = connect();
86 |
87 | app.use("/discovery", discovery({
88 | resources: [
89 | "test/fixtures/discovery/resources1",
90 | "test/fixtures/discovery/resources2",
91 | "test/fixtures/discovery/resources3"
92 | ],
93 | testresources: [
94 | "test/fixtures/discovery/test-resources1",
95 | "test/fixtures/discovery/test-resources2",
96 | "test/fixtures/discovery/test-resources3"
97 | ]
98 | }));
99 |
100 | const server = http.createServer(app).listen(8080);
101 |
102 | http.get("http://localhost:8080/discovery/all_tests", function(res) {
103 | let responseData = "";
104 | res.on("data", function(data) {
105 | responseData += data;
106 | });
107 | res.on("end", function() {
108 | assert.equal(responseData, JSON.stringify({
109 | "all_tests": [
110 | {
111 | lib: "my.ui.lib",
112 | name: "qunit/MyControl.qunit.html",
113 | url: "../my/ui/lib/qunit/MyControl.qunit.html"
114 | },
115 | {
116 | lib: "my.legacy.ui.lib",
117 | name: "MyControl.htm",
118 | url: "../my/legacy/ui/lib/MyControl.htm"
119 | },
120 | {
121 | lib: "my.ui.l",
122 | name: "qunit/MyControl3.qunit.html",
123 | url: "../my/ui/l/qunit/MyControl3.qunit.html"
124 | }
125 | ]
126 | }));
127 |
128 | server.close();
129 | done();
130 | });
131 | });
132 | });
133 | });
134 |
--------------------------------------------------------------------------------
/test/fixtures/discovery/app-resources1/index.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-archive/connect-openui5/d9a4d0625342068cf2313effb6a69a2e34aa8330/test/fixtures/discovery/app-resources1/index.html
--------------------------------------------------------------------------------
/test/fixtures/discovery/app-resources2/foo/bar.htm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-archive/connect-openui5/d9a4d0625342068cf2313effb6a69a2e34aa8330/test/fixtures/discovery/app-resources2/foo/bar.htm
--------------------------------------------------------------------------------
/test/fixtures/discovery/resources1/my/ui/lib/.library:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-archive/connect-openui5/d9a4d0625342068cf2313effb6a69a2e34aa8330/test/fixtures/discovery/resources1/my/ui/lib/.library
--------------------------------------------------------------------------------
/test/fixtures/discovery/resources2/my/legacy/ui/lib/my.legacy.ui.lib.library:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-archive/connect-openui5/d9a4d0625342068cf2313effb6a69a2e34aa8330/test/fixtures/discovery/resources2/my/legacy/ui/lib/my.legacy.ui.lib.library
--------------------------------------------------------------------------------
/test/fixtures/discovery/resources3/my/ui/l/.library:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-archive/connect-openui5/d9a4d0625342068cf2313effb6a69a2e34aa8330/test/fixtures/discovery/resources3/my/ui/l/.library
--------------------------------------------------------------------------------
/test/fixtures/discovery/test-resources1/my/ui/lib/qunit/MyControl.qunit.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-archive/connect-openui5/d9a4d0625342068cf2313effb6a69a2e34aa8330/test/fixtures/discovery/test-resources1/my/ui/lib/qunit/MyControl.qunit.html
--------------------------------------------------------------------------------
/test/fixtures/discovery/test-resources2/my/legacy/ui/lib/MyControl.htm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-archive/connect-openui5/d9a4d0625342068cf2313effb6a69a2e34aa8330/test/fixtures/discovery/test-resources2/my/legacy/ui/lib/MyControl.htm
--------------------------------------------------------------------------------
/test/fixtures/discovery/test-resources3/my/ui/l/qunit/MyControl3.qunit.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SAP-archive/connect-openui5/d9a4d0625342068cf2313effb6a69a2e34aa8330/test/fixtures/discovery/test-resources3/my/ui/l/qunit/MyControl3.qunit.html
--------------------------------------------------------------------------------
/test/fixtures/less/test/themes/mytheme/library.source.less:
--------------------------------------------------------------------------------
1 | @myVar: #000000;
2 |
3 | .myRule {
4 | color: @myVar;
5 | float: left;
6 | }
7 |
--------------------------------------------------------------------------------
/test/fixtures/properties/test.properties:
--------------------------------------------------------------------------------
1 | FOO=B\u00C4R
2 |
--------------------------------------------------------------------------------
/test/less_test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | "use strict";
3 |
4 | const http = require("http");
5 | const assert = require("assert");
6 | const connect = require("connect");
7 | const less = require("../").less;
8 |
9 | describe("less middleware", function() {
10 | it("should return \"library.css\" with correct content", function(done) {
11 | const app = connect();
12 |
13 | app.use(less({
14 | rootPaths: ["test/fixtures/less"]
15 | }));
16 |
17 | const server = http.createServer(app).listen(8080);
18 |
19 | http.get("http://localhost:8080/test/themes/mytheme/library.css", function(res) {
20 | assert.equal(res.headers["content-type"], "text/css");
21 |
22 | let responseData = "";
23 |
24 | res.on("data", function(data) {
25 | responseData += data;
26 | });
27 |
28 | res.on("end", function() {
29 | assert.equal(
30 | responseData, ".myRule {\n color: #000000;\n float: left;\n}\n\n" +
31 | "/* Inline theming parameters */\n" +
32 | "#sap-ui-theme-test{" +
33 | "background-image:url('data:text/plain;utf-8,%7B%22myVar%22%3A%22%23000000%22%7D')}\n"
34 | );
35 | server.close();
36 | done();
37 | });
38 | });
39 | });
40 |
41 | it("should return \"library-RTL.css\" with correct content", function(done) {
42 | const app = connect();
43 |
44 | app.use(less({
45 | rootPaths: ["test/fixtures/less"]
46 | }));
47 |
48 | const server = http.createServer(app).listen(8080);
49 |
50 | http.get("http://localhost:8080/test/themes/mytheme/library-RTL.css", function(res) {
51 | assert.equal(res.headers["content-type"], "text/css");
52 |
53 | let responseData = "";
54 |
55 | res.on("data", function(data) {
56 | responseData += data;
57 | });
58 |
59 | res.on("end", function() {
60 | assert.equal(
61 | responseData, ".myRule {\n color: #000000;\n float: right;\n}\n\n" +
62 | "/* Inline theming parameters */\n" +
63 | "#sap-ui-theme-test{" +
64 | "background-image:url('data:text/plain;utf-8,%7B%22myVar%22%3A%22%23000000%22%7D')}\n"
65 | );
66 | server.close();
67 | done();
68 | });
69 | });
70 | });
71 |
72 | it("should return \"library-parameters.json\" with correct content", function(done) {
73 | const app = connect();
74 |
75 | app.use(less({
76 | rootPaths: ["test/fixtures/less"]
77 | }));
78 |
79 | const server = http.createServer(app).listen(8080);
80 |
81 | http.get("http://localhost:8080/test/themes/mytheme/library-parameters.json", function(res) {
82 | assert.equal(res.headers["content-type"], "application/json");
83 |
84 | let responseData = "";
85 |
86 | res.on("data", function(data) {
87 | responseData += data;
88 | });
89 |
90 | res.on("end", function() {
91 | assert.equal(responseData, JSON.stringify({
92 | myVar: "#000000"
93 | }, null, "\t"));
94 | server.close();
95 | done();
96 | });
97 | });
98 | });
99 | });
100 |
--------------------------------------------------------------------------------
/test/mergeUrls_test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | "use strict";
3 |
4 | const proxy = require("../").proxy;
5 | const assert = require("assert");
6 |
7 | function test(sRemoteLocation, pUrl, expected) {
8 | const uri = proxy._createUri(pUrl, sRemoteLocation);
9 | const url = proxy._buildRequestUrl(uri);
10 | assert.equal(url, expected);
11 | }
12 |
13 | describe("test create URL", function() {
14 | it("no path && no path", function() {
15 | test("http://localhost:1234", "", "/");
16 | });
17 |
18 | it("no path / && no path", function() {
19 | test("http://localhost:1234", "/", "/");
20 | });
21 |
22 |
23 | it("path && no path", function() {
24 | test("http://localhost:1234", "/foo/bar", "/foo/bar");
25 | });
26 |
27 | it("path && path", function() {
28 | test("http://localhost:1234/rfoo/rbar", "/foo/bar", "/rfoo/rbar/foo/bar");
29 | });
30 |
31 |
32 | it("path && query", function() {
33 | test("http://localhost:1234?rtest=1234", "/foo/bar", "/foo/bar?rtest=1234");
34 | });
35 |
36 | it("path && / query", function() {
37 | test("http://localhost:1234/?rtest=1234", "/foo/bar", "/foo/bar?rtest=1234");
38 | });
39 |
40 | it("path && path query", function() {
41 | test("http://localhost:1234/rfoo/rbar?rtest=1234", "/foo/bar", "/rfoo/rbar/foo/bar?rtest=1234");
42 | });
43 |
44 | it("path && path / query", function() {
45 | test("http://localhost:1234/rfoo/rbar/?rtest=1234", "/foo/bar", "/rfoo/rbar/foo/bar?rtest=1234");
46 | });
47 |
48 |
49 | it("query && path", function() {
50 | test("http://localhost:1234/rfoo/rbar", "?test=1234", "/rfoo/rbar?test=1234");
51 | });
52 |
53 | it("query path && query", function() {
54 | test("http://localhost:1234?rtest=1234", "/foo/bar?test=1234", "/foo/bar?rtest=1234&test=1234");
55 | });
56 |
57 | it("query path && / query", function() {
58 | test("http://localhost:1234/?rtest=1234", "/foo/bar?test=1234", "/foo/bar?rtest=1234&test=1234");
59 | });
60 |
61 |
62 | it("query path && path query", function() {
63 | test("http://localhost:1234/rfoo/rbar?rtest=1234", "/foo/bar?test=1234", "/rfoo/rbar/foo/bar?rtest=1234&test=1234");
64 | });
65 |
66 | it("query path && path / query", function() {
67 | test("http://localhost:1234/rfoo/rbar/?rtest=1234", "/foo/bar?test=1234", "/rfoo/rbar/foo/bar?rtest=1234&test=1234");
68 | });
69 |
70 | it("query path && path / query", function() {
71 | test("http://localhost:1234/rfoo/rbar/?rtest1=1234&rtest2=4567", "/foo/bar?test1=1234&test2=4567", "/rfoo/rbar/foo/bar?rtest1=1234&rtest2=4567&test1=1234&test2=4567");
72 | });
73 | });
74 |
--------------------------------------------------------------------------------
/test/properties_test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | "use strict";
3 |
4 | const http = require("http");
5 | const assert = require("assert");
6 | const connect = require("connect");
7 | const serveStatic = require("serve-static");
8 | const properties = require("../").properties;
9 |
10 | describe("properties middleware", function() {
11 | it("should return \"test.properties\" with correct Content-Type header", function(done) {
12 | const app = connect();
13 |
14 | app.use(properties());
15 | app.use("/", serveStatic("test/fixtures/properties"));
16 |
17 | const server = http.createServer(app).listen(8080);
18 |
19 | http.get("http://localhost:8080/test.properties", function(res) {
20 | assert.equal(res.headers["content-type"], "text/plain; charset=ISO-8859-1");
21 |
22 | let responseData = "";
23 |
24 | res.on("data", function(data) {
25 | responseData += data;
26 | });
27 |
28 | res.on("end", function() {
29 | assert.equal(responseData.replace(/(\n)$/, ""), "FOO=B\\u00C4R");
30 | server.close();
31 | done();
32 | });
33 | });
34 | });
35 | });
36 |
--------------------------------------------------------------------------------
/test/proxy-rewrite-cookies_test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | "use strict";
3 |
4 | const assert = require("assert");
5 | const rewriteCookies = require("../lib/proxy-rewrite-cookies");
6 |
7 | describe("proxy-rewrite-cookies", function() {
8 | it("should return empty array when no value is provided", function() {
9 | assert.deepEqual(rewriteCookies(), []);
10 | });
11 | it("should return empty array when empty string is provided", function() {
12 | assert.deepEqual(rewriteCookies(""), []);
13 | });
14 | it("should return empty array when empty array is provided", function() {
15 | assert.deepEqual(rewriteCookies([]), []);
16 | });
17 | it("should return cookie with only key / value", function() {
18 | assert.deepEqual(rewriteCookies("foo=bar"), ["foo=bar"]);
19 | });
20 | it("should return multiple cookies with only key / value", function() {
21 | assert.deepEqual(rewriteCookies(["foo=1", "bar=2"]), ["foo=1", "bar=2"]);
22 | });
23 | it("should remove secure attribute", function() {
24 | assert.deepEqual(rewriteCookies(["foo=bar; Secure;"]), ["foo=bar"]);
25 | });
26 | it("should remove domain attribute", function() {
27 | assert.deepEqual(rewriteCookies(["foo=bar; Domain=example.com;"]), ["foo=bar"]);
28 | });
29 | it("should remove path attribute", function() {
30 | assert.deepEqual(rewriteCookies(["foo=bar; Path=/foo;"]), ["foo=bar"]);
31 | });
32 | it("should remove samesite attribute", function() {
33 | assert.deepEqual(rewriteCookies(["foo=bar; SameSite=Lax;"]), ["foo=bar"]);
34 | });
35 | it("should NOT remove Expires attribute", function() {
36 | assert.deepEqual(rewriteCookies(
37 | ["foo=bar; Expires=Fri, 09-Oct-2020 10:00:00 GMT;"]),
38 | ["foo=bar; Expires=Fri, 09 Oct 2020 10:00:00 GMT"]);
39 | });
40 | it("should NOT remove Max-Age attribute", function() {
41 | assert.deepEqual(rewriteCookies(
42 | ["foo=bar; Max-Age=123;"]),
43 | ["foo=bar; Max-Age=123"]);
44 | });
45 | it("should NOT remove HttpOnly attribute", function() {
46 | assert.deepEqual(rewriteCookies(
47 | ["foo=bar; HttpOnly;"]),
48 | ["foo=bar; HttpOnly"]);
49 | });
50 | it("should handle all attributes at once", function() {
51 | assert.deepEqual(rewriteCookies(
52 | ["foo=bar; Secure; Domain=example.com; Expires=Fri, 09-Oct-2020 10:00:00 GMT; " +
53 | "Path=/foo; Max-Age=123; SameSite=Lax; HttpOnly;"]),
54 | ["foo=bar; Max-Age=123; Expires=Fri, 09 Oct 2020 10:00:00 GMT; HttpOnly"]);
55 | });
56 | it("should not change the value (no decoding / encoding)", function() {
57 | assert.deepEqual(rewriteCookies(
58 | ["foo=bar=1"]),
59 | ["foo=bar=1"]);
60 | assert.deepEqual(rewriteCookies(
61 | ["equation=E%3Dmc%5E2"]),
62 | ["equation=E%3Dmc%5E2"]);
63 | });
64 | });
65 |
--------------------------------------------------------------------------------
/test/proxy_ignore_remote_location_test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | "use strict";
3 |
4 | const http = require("http");
5 | const assert = require("assert");
6 | const connect = require("connect");
7 |
8 | // avoid spawning a new process
9 | delete require.cache[require.resolve("../lib/proxy")];
10 | process.env.REMOTE_LOCATION = "http://localhost:8085";
11 | const proxy = require("../lib/proxy");
12 | delete require.cache[require.resolve("../lib/proxy")];
13 |
14 | describe("IGNORE remote location", function() {
15 | it("should proxy from one server to the server and IGNORE remote location", function(fnDone) {
16 | // check environment
17 | assert.equal(proxy._env.remoteLocation, "http://localhost:8085");
18 |
19 | const sExpectedResponse = "All ok!";
20 | const sExpectedPath = "/foo/bar?pA=1&pB=2";
21 | const iExpectedStatusCode = 200;
22 | const oAppToBeProxied = connect();
23 | let sActualResponse = "";
24 | let sActualPath;
25 | let iActualStatusCode;
26 |
27 | oAppToBeProxied.use(function(oRequest, oResponse) {
28 | // no x-forwarded headers expected (wasn't configured in proxy)
29 | assert.equal(oRequest.headers["x-forwarded-for"], undefined);
30 | assert.equal(oRequest.headers["x-forwarded-port"], undefined);
31 | assert.equal(oRequest.headers["x-forwarded-proto"], undefined);
32 | sActualPath = oRequest.url;
33 | oResponse.end(sExpectedResponse);
34 | });
35 |
36 | const oServerToBeProxied = http.createServer(oAppToBeProxied);
37 | oServerToBeProxied.listen(8080);
38 |
39 | const oProxyApp = connect();
40 | oProxyApp.use(proxy());
41 | const oProxyServer = http.createServer(oProxyApp);
42 | oProxyServer.listen(9000);
43 | oServerToBeProxied.on("close", function() {
44 | oProxyServer.close();
45 | });
46 |
47 | // should still proxy to port 8080 and not to port 8085
48 | http.get("http://localhost:9000/http/localhost:8080" + sExpectedPath, function(oResponse) {
49 | oResponse.on("data", function(oData) {
50 | sActualResponse += oData;
51 | });
52 | iActualStatusCode = oResponse.statusCode;
53 | oResponse.on("end", function() {
54 | assert.equal(sActualPath, sExpectedPath);
55 | assert.equal(sActualResponse, sExpectedResponse);
56 | assert.equal(iActualStatusCode, iExpectedStatusCode);
57 | oProxyServer.on("close", fnDone);
58 | oServerToBeProxied.close();
59 | });
60 | });
61 | });
62 | });
63 |
64 |
--------------------------------------------------------------------------------
/test/proxy_test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | "use strict";
3 |
4 | const http = require("http");
5 | const assert = require("assert");
6 | const connect = require("connect");
7 | const proxy = require("../").proxy;
8 |
9 | describe("proxy middleware should proxy generic requests", function() {
10 | it("should proxy from one server to the other", function(done) {
11 | const sExpectedResponse = "All ok!";
12 | const sExpectedPath = "/foo/bar";
13 | const iExpectedStatusCode = 200;
14 | const oAppToBeProxied = connect();
15 | let sActualResponse = "";
16 | let sActualPath;
17 | let iActualStatusCode;
18 |
19 | oAppToBeProxied.use(function(oRequest, oResponse) {
20 | // no x-forwareded headers expected (wasn't configured in proxy)
21 | assert.equal(oRequest.headers["x-forwarded-for"], undefined);
22 | assert.equal(oRequest.headers["x-forwarded-port"], undefined);
23 | assert.equal(oRequest.headers["x-forwarded-proto"], undefined);
24 | sActualPath = oRequest.url;
25 | oResponse.setHeader("Set-Cookie", [
26 | "a=b; Secure; HttpOnly; Max-Age=5; SameSite=Strict",
27 | "c=d; Domain=example.com; HttpOnly; Expires=expires=Fri, 09-Oct-2020 10:00:00 GMT; Path=/foo"
28 | ]);
29 | oResponse.end(sExpectedResponse);
30 | });
31 |
32 | const oServerToBeProxied = http.createServer(oAppToBeProxied);
33 | oServerToBeProxied.listen(8080);
34 |
35 | const oProxyApp = connect();
36 | oProxyApp.use(proxy());
37 | const oProxyServer = http.createServer(oProxyApp);
38 | oProxyServer.listen(9000);
39 |
40 | http.get("http://localhost:9000/http/localhost:8080" + sExpectedPath, function(oResponse) {
41 | oResponse.on("data", function(oData) {
42 | sActualResponse += oData;
43 | });
44 | iActualStatusCode = oResponse.statusCode;
45 | oResponse.on("end", function() {
46 | assert.equal(sActualPath, sExpectedPath);
47 | assert.equal(sActualResponse, sExpectedResponse);
48 | assert.equal(iActualStatusCode, iExpectedStatusCode);
49 |
50 | const cookies = oResponse.headers["set-cookie"];
51 | ["secure", "domain", "path", "samesite"].forEach(function(attribute) {
52 | const hasAttribute = cookies.some(function(cookie) {
53 | return cookie.toLowerCase().includes(attribute);
54 | });
55 | assert.ok(!hasAttribute, attribute + " attribute should be removed from the cookies");
56 | });
57 |
58 | oServerToBeProxied.close();
59 | oProxyServer.close();
60 | done();
61 | });
62 | });
63 | });
64 | it("should proxy by respecting custom options", function(done) {
65 | const sExpectedResponse = "All ok!";
66 | const sExpectedPath = "/foo/bar";
67 | const iExpectedStatusCode = 200;
68 | const oAppToBeProxied = connect();
69 | let sActualResponse = "";
70 | let sActualPath;
71 | let iActualStatusCode;
72 |
73 | oAppToBeProxied.use(function(oRequest, oResponse) {
74 | // x-forwareded headers are expected (see xfwd option in proxy config)
75 | assert(
76 | oRequest.headers["x-forwarded-for"] === "127.0.0.1" ||
77 | oRequest.headers["x-forwarded-for"] === "::ffff:127.0.0.1"
78 | );
79 | assert.equal(oRequest.headers["x-forwarded-port"], "8080");
80 | assert.equal(oRequest.headers["x-forwarded-proto"], "http");
81 | sActualPath = oRequest.url;
82 | oResponse.end(sExpectedResponse);
83 | });
84 |
85 | const oServerToBeProxied = http.createServer(oAppToBeProxied);
86 | oServerToBeProxied.listen(8080);
87 |
88 | const oProxyApp = connect();
89 | oProxyApp.use(proxy({
90 | xfwd: true
91 | }));
92 | const oProxyServer = http.createServer(oProxyApp);
93 | oProxyServer.listen(9000);
94 |
95 | http.get("http://localhost:9000/http/localhost:8080" + sExpectedPath, function(oResponse) {
96 | oResponse.on("data", function(oData) {
97 | sActualResponse += oData;
98 | });
99 | iActualStatusCode = oResponse.statusCode;
100 | oResponse.on("end", function() {
101 | assert.equal(sActualPath, sExpectedPath);
102 | assert.equal(sActualResponse, sExpectedResponse);
103 | assert.equal(iActualStatusCode, iExpectedStatusCode);
104 |
105 | oServerToBeProxied.close();
106 | oProxyServer.close();
107 | done();
108 | });
109 | });
110 | });
111 | });
112 |
--------------------------------------------------------------------------------
/test/proxy_use_remote_location_test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | "use strict";
3 |
4 | const http = require("http");
5 | const assert = require("assert");
6 | const connect = require("connect");
7 |
8 | // avoid spawning a new process
9 | delete require.cache[require.resolve("../lib/proxy")];
10 | process.env.REMOTE_LOCATION = "http://localhost:8080";
11 | const proxy = require("../lib/proxy");
12 | delete require.cache[require.resolve("../lib/proxy")];
13 |
14 | describe("USE remote location", function() {
15 | it("should proxy from one server to the server and USE remote location", function(fnDone) {
16 | // check environment
17 | assert.equal(proxy._env.remoteLocation, "http://localhost:8080");
18 |
19 | const sExpectedResponse = "All ok!";
20 | const sExpectedPath = "/foo/bar?pA=1&pB=2";
21 | const iExpectedStatusCode = 200;
22 | const oAppToBeProxied = connect();
23 | let sActualResponse = "";
24 | let sActualPath;
25 | let iActualStatusCode;
26 |
27 | oAppToBeProxied.use(function(oRequest, oResponse) {
28 | // no x-forwarded headers expected (wasn't configured in proxy)
29 | assert.equal(oRequest.headers["x-forwarded-for"], undefined);
30 | assert.equal(oRequest.headers["x-forwarded-port"], undefined);
31 | assert.equal(oRequest.headers["x-forwarded-proto"], undefined);
32 | sActualPath = oRequest.url;
33 | oResponse.end(sExpectedResponse);
34 | });
35 |
36 | const oServerToBeProxied = http.createServer(oAppToBeProxied);
37 | oServerToBeProxied.listen(8080);
38 |
39 | const oProxyApp = connect();
40 | oProxyApp.use(proxy());
41 | const oProxyServer = http.createServer(oProxyApp);
42 | oProxyServer.listen(9000);
43 | oServerToBeProxied.on("close", function() {
44 | oProxyServer.close();
45 | });
46 |
47 | // should proxy to port 8080
48 | http.get("http://localhost:9000" + sExpectedPath, function(oResponse) {
49 | oResponse.on("data", function(oData) {
50 | sActualResponse += oData;
51 | });
52 | iActualStatusCode = oResponse.statusCode;
53 | oResponse.on("end", function() {
54 | assert.equal(sActualPath, sExpectedPath);
55 | assert.equal(sActualResponse, sExpectedResponse);
56 | assert.equal(iActualStatusCode, iExpectedStatusCode);
57 | oProxyServer.on("close", fnDone);
58 | oServerToBeProxied.close();
59 | });
60 | });
61 | });
62 | });
63 |
64 |
--------------------------------------------------------------------------------