Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
360 changes: 210 additions & 150 deletions TODO.md

Large diffs are not rendered by default.

38 changes: 26 additions & 12 deletions infra/proxy/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,35 @@ Nginx reverse proxy with njs (JavaScript) for header/cookie manipulation. Used t
- `.env` - **gitignored** - contains vnext-specific config
- `.env.example` - template for the above

The vnext layer also owns **OS host variants**: letting named users be switched onto a
different OutSystems host from the rest of their environment.

- `configuration/config.<env>.<variant>.json` is the environment's config with only the OS
host swapped (enforced by `outsystems-host-consistency.spec.ts`), deployed beside
`config.json` as `config.<variant>.json`.
- `OS_HOST_VARIANTS` in `global-components.vnext.ts` maps each variant to its host. A unit
test checks it against the variant files both ways.
- The switch is the `Gloco-Os-Target-<env>` cookie (`Path=/`, value = the variant's OS host),
set via `PUT`/`DELETE /global-components/os-target/<env>` from the preview page.
- `/global-components/<env>/config.json` is served by `readConfigBlobName`:
### Multi-OS-domain testing (`config/global-components.multi-os-domain-testing/`) — TEMPORARY

A self-contained module (FCT2-22132) that lets designated QA users run against a different
OutSystems host (the oapps proxy, the London tenant) while everyone else is untouched. It only
ADDS locations; where one shadows an existing route, a request without the signal cookie is
handed straight back to that route's own block. To end the trial, delete the module directory
and its lines in `scripts/build.sh`, `deploy/deploy.sh`, `deploy/rollback.sh`, `run-tests.sh`,
`package.json` and `docker/` (`docker-compose.multi-os-domain-testing.yml`,
`test-only.polaris-launch.conf`).

- **Signal:** the `Gloco-Os-Target-<env>` cookie (`Path=/`, `HttpOnly`, value = the chosen OS
host). Edge and IE mode keep separate cookie stores, so it is written into both by
`/global-components/multi-os/set?env=&host=&return=`, the only writer. That route flips the
tab between engines with `X-InternetExplorerMode`. An empty `host` clears both copies.
`/global-components/multi-os/target/<env>` reports the current value to the preview page.
- **Variants:** `configuration/config.<env>.<variant>.json` is the environment's config with
only the OS host swapped (enforced by `outsystems-host-consistency.spec.ts`), deployed beside
`config.json` as `config.<variant>.json`. `OS_HOST_VARIANTS` maps each variant to its host; a
unit test checks it against the files both ways.
- **`config.json`:** served by `readConfigBlobName`:
- the variant for the requesting OS page's own host (by `Origin`); else
- the variant the cookie names (CWA); else
- `config.json`.
- Polaris's `/init` reads the same cookie to move the handover onto the switched host.
- **Proxied-CMS C-button:** exact-match overrides of Polaris's `/launch/cin2`–`cin5-proxy`.
- Without the signal, they rewrite to `…-proxy/`, which only Polaris's prefix locations match,
so Polaris's own redirect runs unchanged.
- With it (the click arrives in IE mode, carrying IE mode's copy), they redirect to Polaris's
same `/polaris?r=<handover>` target, with the OS host swapped.
- `/polaris`, `/init`, raw-CMS `/launch/cinN` and prod's `/launch/cms-proxy` are not touched.

### Docker (`docker/`)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# ---------------------------------------------------------------------------
# Multi-OS-domain testing (FCT2-22132) — TEMPORARY
#
# Lets designated QA users run against a different OutSystems host (the oapps
# proxy, the London tenant) while everyone else is untouched. See the header of
# global-components.multi-os-domain-testing.ts for the design. When the trial is
# over, delete this module (and its build/deploy/test wiring) — nothing else
# depends on it, and it edits nothing else: it only ADDS locations. Where one of
# them shadows an existing route, a request without the signal cookie is handed
# straight back to that route's own block, unchanged.
#
# Picked up by `include global-components*.conf;` in the server block, next to
# Polaris's own locations and the other global-components confs.
# ---------------------------------------------------------------------------

js_import glocomultios from templates/global-components.multi-os-domain-testing.js;

js_set $gloco_config_blob glocomultios.readConfigBlobName;
js_set $gloco_multi_os_launch glocomultios.launchTarget;

# ---- config.json selection -------------------------------------------------
#
# config.json is served as config.json or config.<variant>.json, chosen by
# readConfigBlobName from the page's Origin (OS pages) or the signal cookie
# (CWA). Exact-match locations win over the main conf's regex location for
# /global-components/<env>/..., so these take over config.json alone and leave
# every other artifact where it is. Each records its environment and hands over
# to one internal location, rather than repeating the proxy block per env.

location = /global-components/dev/config.json { set $gloco_config_env dev; rewrite ^ /global-components/__config last; }
location = /global-components/test/config.json { set $gloco_config_env test; rewrite ^ /global-components/__config last; }
location = /global-components/uat/config.json { set $gloco_config_env uat; rewrite ^ /global-components/__config last; }
location = /global-components/prod/config.json { set $gloco_config_env prod; rewrite ^ /global-components/__config last; }

location = /global-components/__config {
internal;

error_page 418 = @gloco_preflight;
if ($request_method = OPTIONS) {
return 418;
}

# As the main conf's artifact location (see its comments for the reasoning).
gzip on;
gzip_types application/json;
gzip_proxied any;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 5;

proxy_hide_header Access-Control-Allow-Origin;
proxy_hide_header Access-Control-Allow-Credentials;
add_header Access-Control-Allow-Origin * always;
# The body depends on who is asking, so no shared cache may reuse it across them.
add_header Vary "Origin, Cookie" always;
add_header X-Gloco-Config $gloco_config_blob always;

resolver ${WEBSITE_DNS_SERVER} ipv6=off valid=30s;
proxy_ssl_server_name on;
proxy_ssl_verify off;
proxy_pass_request_headers off;
proxy_set_header Host ${CPS_GLOBAL_COMPONENTS_BLOB_STORAGE_DOMAIN};
proxy_pass https://${CPS_GLOBAL_COMPONENTS_BLOB_STORAGE_DOMAIN}/$gloco_config_env/$gloco_config_blob;
}

# ---- Proxied-CMS C-button --------------------------------------------------
#
# The proxied CMS's C-button points at /launch/<cin>-proxy (Polaris rewrites
# CMS's CASEWORK_TOOLS_URL to it in uainGeneratedScript.aspx). Polaris serves
# those as PREFIX locations (`location /launch/cin3-proxy { return 302 ...; }`),
# so these EXACT matches take precedence for that one URL:
# - no signal: rewrite to the same path plus "/", which only Polaris's prefix
# location matches, so THEIR block runs, exactly as today (and follows any
# change they make to it);
# - signal: send the user through the same handover chain, on the chosen host.
# The click arrives in IE mode, so the cookie read is the IE-mode copy that the
# set route wrote. /polaris and /init then run completely unchanged.

location = /launch/cin2-proxy {
if ($gloco_multi_os_launch = "") {
rewrite ^ /launch/cin2-proxy/ last;
}
return 302 $gloco_multi_os_launch;
}

location = /launch/cin3-proxy {
if ($gloco_multi_os_launch = "") {
rewrite ^ /launch/cin3-proxy/ last;
}
return 302 $gloco_multi_os_launch;
}

location = /launch/cin4-proxy {
if ($gloco_multi_os_launch = "") {
rewrite ^ /launch/cin4-proxy/ last;
}
return 302 $gloco_multi_os_launch;
}

location = /launch/cin5-proxy {
if ($gloco_multi_os_launch = "") {
rewrite ^ /launch/cin5-proxy/ last;
}
return 302 $gloco_multi_os_launch;
}

# ---- The switch (driven by the preview page, same-origin, so no CORS) -------

# The only writer of the signal: visits both engines to set/clear both copies.
location = /global-components/multi-os/set {
js_content glocomultios.handleSet;
}

location ~ ^/global-components/multi-os/target/(dev|test|uat|prod)$ {
js_content glocomultios.handleStatus;
}
Loading
Loading