From 188bcce617cbfc6d17d35a4e31d15910d866ca6b Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Fri, 29 Aug 2025 11:30:35 +0200 Subject: [PATCH 01/19] 4565: Started developer documentation rewrite --- CHANGELOG.md | 1 - README.md | 204 +++++++++++++++++++++++++++-- docs/changelogs/docs.md | 228 --------------------------------- docs/readmes/admin.md | 84 ------------ docs/readmes/client.md | 2 +- docs/readmes/grid-generator.md | 15 --- docs/readmes/template.md | 128 ------------------ docs/test.md | 4 +- 8 files changed, 194 insertions(+), 472 deletions(-) delete mode 100644 docs/changelogs/docs.md delete mode 100644 docs/readmes/admin.md delete mode 100644 docs/readmes/template.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c2777af..62bfeccd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,4 +24,3 @@ Therefore, changelogs were maintained for each repo. These are available here: * Admin: [docs/changelogs/admin.md](docs/changelogs/admin.md) * Template: [docs/changelogs/template.md](docs/changelogs/template.md) * Client: [docs/changelogs/client.md](docs/changelogs/client.md) -* Docs: [docs/changelogs/docs.md](docs/changelogs/docs.md) diff --git a/README.md b/README.md index 50508dd4..7ca957e4 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,46 @@ # OS2Display -## Development +## Description + +The purpose of OS2Display is to deliver content to information screens. +At the core, is the API that clients can connect to. All data runs through this API. +The project also includes an Admin for creating content and a Client for displaying the content. +The system is browser-based. + +Further documentation can be found in the +[https://os2display.github.io/display-docs/](https://os2display.github.io/display-docs/). + +## Technologies + +The API is written in PHP with Symfony and API Platform as frameworks. + +The Admin and Client are written in javascript and React. + +## Taskfile + +The project ships with a [taskfile](https://taskfile.dev/) for executing common commands. + +For a list of commands, run: + +```shell +task --list-all +``` + +## Development setup + +To get started with the development setup, run the following task command: + +```bash +task site-install +``` + +or without taskfile: ```bash docker compose pull +docker compose run --rm node npm install docker compose up --detach docker compose exec phpfpm composer install -docker compose run --rm node npm install # Run migrations docker compose exec phpfpm bin/console doctrine:migrations:migrate @@ -21,9 +55,149 @@ The fixtures have an editor user: with the password: "apass The fixtures have the image-text template, and two screen layouts: full screen and "two boxes". -## Description +## Production setup + +In `.env.local` set the following values: + +```text +APP_ENV=prod +APP_SECRET= +``` + +TODO: Add further instructions. -TODO +## Coding standards + +Before a PR can be merged it has to pass the Github Actions checks. See `.github/workflows`. + +Run the coding standards checks: + +```shell +task coding-standards:check +``` + +Apply automatic fixes: + +```shell +task coding-standards:apply +``` + +## Stateless + +The API is stateless except `/v2/authentication` routes. +Make sure to set the `CORS_ALLOW_ORIGIN` correctly in `.env.local`. + +## OIDC providers + +At the present two possible oidc providers are implemented: 'internal' and 'external'. +These work differently. + +The internal provider is expected to handle both authentication and authorization. +Any users logging in through the internal will be granted access based on the +tenants/roles provided. + +The external provider only handles authentication. A user logging in through the +external provider will not be granted access automatically, but will be challenged +to enter an activation (invite) code to verify access. + +### Internal + +The internal oidc provider gets that user's name, email and tenants from claims. + +The claim keys needed are set in the env variables: + +- `INTERNAL_OIDC_CLAIM_NAME` +- `INTERNAL_OIDC_CLAIM_EMAIL` +- `INTERNAL_OIDC_CLAIM_GROUPS` + +The value of the claim with the name that is defined in the env variable `INTERNAL_OIDC_CLAIM_GROUPS` is mapped to +the user's access to tenants in `App\Security\AzureOidcAuthenticator`. The claim field should consist of an array of +names that should follow the following structure ``. +`` can be `Admin` or `Redaktoer` (editor). +E.g. `Example1Admin` will map to the tenant with name `Example1` with `ROLE_ADMIN`. +If the tenant does not exist it will be created when the user logs in. + +### External + +The external oidc provider takes only the claim defined in the env variable +OIDC_EXTERNAL_CLAIM_ID, hashes it and uses this hash as providerId for the user. +When a user logs in with this provider, it is initially not in any tenant. +To be added to a tenant the user has to use an activation code a +ROLE_EXTERNAL_USER_ADMIN has created. + +## JWT Auth + +To authenticate against the API locally you must generate a private/public key pair: + +```shell +docker compose exec phpfpm bin/console lexik:jwt:generate-keypair +``` + +Then create a local test user if needed: + +```shell +docker compose exec phpfpm bin/console app:user:add +``` + +You can now obtain a token by sending a `POST` request to the +`/v2/authentication/token` endpoint: + +```curl +curl --location --request 'POST' \ + 'https://display.local.itkdev.dk/v2/authentication/token' \ + --header 'accept: application/json' \ + --header 'Content-Type: application/json' \ + --data '{ + "email": "editor@example.com", + "password": "apassword" +}' +``` + +Either on the command line or through the OpenApi docs at `/docs` + +You can use the token either by clicking "Authorize" in the docs and entering + +```curl +Bearer +``` + +as the api key value. Or by adding an auth header to your requests + +```curl +curl --location --request 'GET' \ + 'https://display.local.itkdev.dk/v2/layouts?page=1&itemsPerPage=10' \ + --header 'accept: application/ld+json' \ + --header 'Authorization: Bearer ' +``` + +## Tests + +### API tests + +Run automated tests for the API: + +```shell +docker compose exec phpfpm composer test-setup +docker compose exec phpfpm composer test +``` + +Disable or hide deprecation warnings using the [`SYMFONY_DEPRECATIONS_HELPER` environment +variable](https://symfony.com/doc/current/components/phpunit_bridge.html#configuration), e.g. + +```shell +docker compose exec --env SYMFONY_DEPRECATIONS_HELPER=disabled phpfpm composer test +``` + +### Admin and Client tests + +To run tests, use the script: + +```shell +./scripts/test.sh +``` + +This script will stop the node container, build the javascript/css assets, and run tests with playwright, +and starts the node container again. ## API specification and generated code @@ -58,22 +232,24 @@ See [https://redux-toolkit.js.org/rtk-query/usage/code-generation](https://redux-toolkit.js.org/rtk-query/usage/code-generation) for information about the code generation. -## Tests - -### API tests +## Configuration -TODO +Configuration of the project should be added to `.env.local`. Default values are set in `.env`. -### Admin and Client tests +## Preview mode in the Client -To run tests, use the script: +The Client can be started in preview mode by setting the following url parameters: -```shell -./scripts/test.sh +```text +preview= +preview-id= +preview-token= +preview-tenant= ``` -This script will stop the node container, build the javascript/css assets, and run tests with playwright, -and starts the node container again. +The preview will use the token and tenant for accessing the data from the api. + +This feature is used in the Admin for displaying previews of slides, playlists and screens. ## Versioning diff --git a/docs/changelogs/docs.md b/docs/changelogs/docs.md deleted file mode 100644 index 5f720154..00000000 --- a/docs/changelogs/docs.md +++ /dev/null @@ -1,228 +0,0 @@ -# Changelog - -## Unreleased changes (currently in test) - -* [API](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#unreleased) -* [Admin](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#unreleased) -* [Client](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#unreleased) -* [Templates](https://github.com/os2display/display-templates/blob/develop/CHANGELOG.md#unreleased) - -## 2025-05-12 - -* Released api `2.5.0`. See [changelog](https://github.com/os2display/display-api-service/blob/2.5.0/CHANGELOG.md#250---2025-05-09). -* Released admin `2.5.0`. See [changelog](https://github.com/os2display/display-admin-client/blob/2.5.0/CHANGELOG.md#250---2025-05-09). -* Released templates `2.5.0`. See [changelog](https://github.com/os2display/display-templates/blob/2.5.0/CHANGELOG.md#250---2025-05-09). -* Released client `2.2.0`. See [changelog](https://github.com/os2display/display-client/blob/2.2.0/CHANGELOG.md#220---2025-05-09). - -## 2025-03-24 - -* Released api `2.3.0`. See [changelog](https://github.com/os2display/display-api-service/blob/2.3.0/CHANGELOG.md#230---2025-03-24). -* Released admin `2.3.0`. See [changelog](https://github.com/os2display/display-admin-client/blob/2.3.0/CHANGELOG.md#230---2025-03-24). -* Released templates `2.3.0`. See [changelog](https://github.com/os2display/display-templates/blob/2.3.0/CHANGELOG.md#230---2025-03-24). - -## 2025-03-17 - -* Released api `2.2.0`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#220---2025-03-17). -* Released admin `2.2.0`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#220---2025-03-17). - -## 2025-03-10 - -* Released templates `2.2.0`. See [changelog](https://github.com/os2display/display-templates/blob/develop/CHANGELOG.md#220---2025-3-10). - -## 2025-01-14 - -* Released api `2.1.4`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#214---2025-01-14). -* Released client `2.1.2`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#212---2024-11-20). -* Released templates `2.1.1`. See [changelog](https://github.com/os2display/display-templates/blob/develop/CHANGELOG.md#211---2024-11-20). - -## 2024-09-04 - -* Added test guides for the remaining templates. - -## 2024-08-14 - -* Added testing guide to docs: [https://os2display.github.io/display-docs/content_structure/test_guide.html](https://os2display.github.io/display-docs/content_structure/test_guide.html). -* Released admin `2.0.3`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#203---2024-08-14). -* Released client `2.0.4`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#204---2024-08-14). -* Released template `2.0.1`. See [changelog](https://github.com/os2display/display-templates/blob/develop/CHANGELOG.md#201---2024-08-14). - -## 2024-06-28 - -* Released api `2.0.6`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#206---2024-06-28). - -## 2024-05-21 - -* Released api `2.0.5`. See [changelog](https://github.com/os2display/display-api-service/blob/main/CHANGELOG.md#205---2024-05-21). -* Released client `2.0.3`. See [changelog](https://github.com/os2display/display-client/blob/main/CHANGELOG.md#203---2024-05-21). - -## 2024-04-25 - -* Released api `2.0.4`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#204---2024-04-25). -* Released admin `2.0.2`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#202---2024-04-25). -* Released client `2.0.2`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#202---2024-04-25) - -## 2024-04-10 - -* Released api `2.0.3`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#203---2024-04-10). -* Released api `2.0.2`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#202---2024-04-10). -* Released admin `2.0.1`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#201---2024-04-10). -* Released client `2.0.1`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#201---2024-04-10) - -## 2024-04-09 - -* Released api `2.0.1`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#201---2024-04-09). -* Released api `2.0.0`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#200---2024-04-09). -* Released admin `2.0.0`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#200---2024-04-09). -* Released client `2.0.0`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#200---2024-04-09) -* Released templates `2.0.0`. See [changelog](https://github.com/os2display/display-templates/blob/develop/CHANGELOG.md#200---2024-04-09) - -## 2023-10-26 - -* Released api `1.5.0`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#150---2023-10-26). -* Released admin `1.5.0`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#150---2023-10-26). -* Released templates `1.3.1`. See [changelog](https://github.com/os2display/display-templates/blob/develop/CHANGELOG.md#131---2023-10-26) - -## 2023-09-14 - -* Released api `1.4.0`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#140---2023-09-14) -* Released admin `1.4.5`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#140---2023-09-14) -* Released client `1.3.4`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#135---2023-09-14) -* Released templates `1.3.0`. See [changelog](https://github.com/os2display/display-templates/blob/develop/CHANGELOG.md#130---2023-09-14) - -## 2023-07-13 - -* Released client `1.3.4`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#134---2023-07-13) - -## 2023-07-11 - -* Released api `1.3.2`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#132---2023-07-11) -* Released api `1.3.1`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#131---2023-07-11) -* Released api `1.3.0`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#130---2023-07-11) -* Released admin `1.3.3`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#133---2023-07-11) -* Released admin `1.3.2`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#132---2023-07-11) -* Released admin `1.3.1`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#131---2023-07-11) -* Released admin `1.3.0`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#130---2023-07-11) -* Released client `1.3.3`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#133---2023-07-11) -* Released client `1.3.2`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#132---2023-07-11) -* Released client `1.3.1`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#131---2023-07-11) -* Released client `1.3.0`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#130---2023-07-11) - -## 2023-06-30 - -* Released api `1.2.9`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#129---2023-06-30) -* Released client `1.2.7`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#127---2023-06-30) - -## 2023-06-12 - -* Released client `1.2.6`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#126---2023-06-12) - -## 2023-06-06 - -* Released client `1.2.5`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#125---2023-06-06). - -## 2023-06-01 - -* Released templates `1.2.6`. See [changelog](https://github.com/os2display/display-templates/blob/develop/CHANGELOG.md#126---2023-06-01) - -## 2023-05-25 - -* Released api `1.2.8`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#128---2023-05-25) -* Released client `1.2.4`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#124---2023-05-25) -* Released admin `1.2.7`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#127---2023-05-25) - -## 2023-05-11 - -* Released admin `1.2.6`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#126---2023-05-11) - -## 2023-04-03 - -* Released api `1.2.7`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#127---2023-04-03). - -## 2023-03-24 - -* Released api `1.2.6`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#126---2023-03-24). -* Released admin `1.2.5`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#125---2023-03-24). -* Released admin `1.2.4`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#124---2023-03-24). -* Released client `1.2.3`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#123---2023-03-24). -* Released templates `1.2.4`. See [changelog](https://github.com/os2display/display-templates/blob/develop/CHANGELOG.md#124---2023-03-24). - -* Released templates `1.2.5`. See [changelog](https://github.com/os2display/display-templates/blob/develop/CHANGELOG.md#125---2023-03-24). - -## 2023-03-16 - -* Released api `1.2.5`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#125---2023-03-16). - -## 2023-03-07 - -* Released api `1.2.4`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#124---2023-03-07). -* Released admin `1.2.3`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#123---2023-03-07). -* Released templates `1.2.3`. See [changelog](https://github.com/os2display/display-templates/blob/develop/CHANGELOG.md#123---2023-03-07). -* Released client `1.2.2`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#122---2023-03-07). - -## 2023-02-14 - -* Released api `1.2.3`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#123---2023-02-14). - -## 2023-02-08 - -* Released api `1.2.2`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#122---2023-02-08). -* Released admin `1.2.2`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#122---2023-02-08). -* Released templates `1.2.2`. See [changelog](https://github.com/os2display/display-templates/blob/develop/CHANGELOG.md#122---2023-02-08). - -## 2023-02-02 - -* Released api `1.2.1`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#121---2023-02-02). - -## 2023-01-13 - -* Released admin `1.2.1`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#121---2023-01-13). -* Released cient `1.2.1`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#121---2023-01-13). - -## 2023-01-05 - -* Released api `1.2.0`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#120---2023-01-05). -* Released admin `1.2.0`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#120---2023-01-05). -* Released client `1.2.0`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#120---2023-01-05). -* Released templates `1.2.0`. See [changelog](https://github.com/os2display/display-templates/blob/develop/CHANGELOG.md#120---2023-01-05). - -## 2022-10-06 - -* Released admin `1.1.0`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#110---2022-10-06). -* Released client `1.1.0`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#110---2022-10-06). - -## 2022-09-29 - -* Released api `1.1.0`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#110---2022-09-29). - -## 2022-09-08 - -* Released client `1.0.2`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#102---2022-09-08). - -## 2022-09-05 - -* Released api `1.0.4`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#104---2022-09-05). -* Released admin `1.0.3`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#103---2022-09-05). - -## 2022-09-01 - -* Released api `1.0.3`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#103---2022-09-01). -* Released api `1.0.2`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#102---2022-09-01). -* Released api `1.0.1`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#101---2022-09-01). - -## 2022-06-02 - -* Released admin `1.0.2`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#102---2022-06-02). -* Released templates `1.0.2`. See [changelog](https://github.com/os2display/display-templates/blob/develop/CHANGELOG.md#102---2022-06-02). -* Released templates `1.0.1`. See [changelog](https://github.com/os2display/display-templates/blob/develop/CHANGELOG.md#101---2022-06-02). - -## 2022-06-01 - -* Released admin `1.0.1`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#101---2022-06-01). -* Released client `1.0.1`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#101---2022-06-01). -* Released templates `1.0.0`. See [changelog](https://github.com/os2display/display-templates/blob/develop/CHANGELOG.md#100---2022-06-01). - -## 2022-05-18 - -* Released api `1.0.0`. See [changelog](https://github.com/os2display/display-api-service/blob/develop/CHANGELOG.md#100---2022-05-18). -* Released admin `1.0.0`. See [changelog](https://github.com/os2display/display-admin-client/blob/develop/CHANGELOG.md#100---2022-05-18). -* Released client `1.0.0`. See [changelog](https://github.com/os2display/display-client/blob/develop/CHANGELOG.md#100---2022-05-18). diff --git a/docs/readmes/admin.md b/docs/readmes/admin.md deleted file mode 100644 index 179d0a87..00000000 --- a/docs/readmes/admin.md +++ /dev/null @@ -1,84 +0,0 @@ -# OS2Display Admin - -This is an admin for OS2Display. This is based on create-react-app. See - for a -description of the admin. - -## Docker development setup - -### Create public/config file - -By default, the api that is requested is located at `/api/`. -This can be configured by: - -```shell -cp public/example_config.json public/config.json -``` - -And modify the entries to suit your setup. - -```json -{ - "api": "[WHERE TO FIND THE API]" -} -``` - -### Create public/access-config file - -This file contains the access config. This file is only required if other access -setting are required than what is default. - -```shell -cp public/example-access-config.json public/access-config.json -``` - -### Up the containers and install npm packages - -```shell -docker compose up --detach -docker compose run --rm node yarn install -``` - -**Note**: When to `node` container is running, the JavaScript is continously -being built. - -### Redux Toolkit - -The communication with the API is generated from an OpenAPI -specification with Redux Toolkit. - -To regenerate (when the API specification has changed): - -```shell -# Action: Replace api.json with the new api.json OpenAPI specification - -# Install and run scripts to generate ned Redux Api slices. -docker compose exec node npm --prefix src/redux/api install -docker compose exec node npm --prefix src/redux/api start -``` - -## Testing with playwright - -We use [playwright](https://playwright.dev/) for testing. - -To run playwright tests with docker: - -```shell - docker compose run --rm playwright npx playwright test -``` - -To test with user interface, up the containers and change the baseUrl in playwright.config.ts, then: - -```shell -yarn playwright test --ui -``` - -### Linting - -```shell -docker compose run --rm node yarn check-coding-standards -``` - -```shell -docker compose run --rm node yarn apply-coding-standards -``` diff --git a/docs/readmes/client.md b/docs/readmes/client.md index 22fdeb08..0551f3cd 100644 --- a/docs/readmes/client.md +++ b/docs/readmes/client.md @@ -46,7 +46,7 @@ preview-token= preview-tenant= ``` -The preview will use the token and tenant for acessing the data from the api. +The preview will use the token and tenant for accessing the data from the api. ## Docker development setup diff --git a/docs/readmes/grid-generator.md b/docs/readmes/grid-generator.md index d3fc8e2e..69c026d8 100644 --- a/docs/readmes/grid-generator.md +++ b/docs/readmes/grid-generator.md @@ -47,18 +47,3 @@ Return: ```text "a / a / d / d" ``` - -## Testing - -With jest - -```bash -yarn test -``` - -## Linting - -```bash -check-coding-standards -apply-coding-standards -``` diff --git a/docs/readmes/template.md b/docs/readmes/template.md deleted file mode 100644 index 79b6c795..00000000 --- a/docs/readmes/template.md +++ /dev/null @@ -1,128 +0,0 @@ -# display-templates - -Contains base templates for OS2Display. -See -[https://github.com/os2display/display-docs/blob/main/templates.md](https://github.com/os2display/display-docs/blob/main/templates.md) -for a description of how to create templates. - -## Develop - -To enable easy development of templates, the supplied docker-compose setup serves a page where the -slides in `src/slides.js` are displayed as a list of templates that can be open. The slides file contains -example content for the different templates. - -`index.html` serves a local setup for working with the templates. - -```bash -docker compose pull -docker compose run --rm node yarn -docker compose up --detach -``` - -The docker setup serves the files in the `build/` (see build for production) folder as `display-templates.local.itkdev.dk/build/`. - -## Add a new template - -To add a template: - -* Create a folder in src with the name of the template, e.g. `my-template` that contains the following files: - * `my-template.js` - The React component to render. - * `my-template.config.json` - The file describing the where to find the files required for the template. - * `my-template-admin.json` - The file describing the content interface for populating the template. - -Add one or more entries to `src/slides.js` with examples of the data required for the template. - -Also import the template in `src/index.js` and add the template to `const renderSlide = {}` in `src/index.js`. - -To compile the template it is necessary to add it to the webpack setup. This is done in `webpack.config.js`. - -Add it to `const entry = {}`: - -```text -{ - "my-template": path.resolve(__dirname, "./src/my-template/my-template.js") -} -``` - -Running the build script will build all templates and set new timestamps in the config json files. -Only add the files relating to the new template to git. - -## Build for production - -To build the templates for production - -```bash -docker compose run --rm node yarn install -docker compose run --rm node yarn build -``` - -To continually build components when files change - -```bash -docker compose run --rm node yarn build-watch -``` - -The compiled files will be placed in `build/`. These should be committed to -git repository, to enable Remote Components to load them in the clients. - -### Build base URL - -The default base build URLs, -`https://raw.githubusercontent.com/os2display/display-templates/develop/build/` -and -`https://raw.githubusercontent.com/os2display/display-templates/main/build/`, -respectively, can be overridden via environment variables: - -Override both with same value: - -```sh -docker compose run --rm --env DEPLOYMENT_BUILD_BASE_URL="http://$(docker compose port nginx 80)/build/" node yarn build -``` - -Override "develop" base URL only: - -```sh -docker compose run --rm --env DEPLOYMENT_BUILD_BASE_URL_DEVELOP="http://$(docker compose port nginx 80)/build/" node yarn build -``` - -Override "main" base URL only: - -```sh -docker compose run --rm --env DEPLOYMENT_BUILD_BASE_URL_MAIN="http://$(docker compose port nginx 80)/build/" node yarn build -``` - -The default behavoir is equivalent to - -```sh -docker compose run --rm \ - --env DEPLOYMENT_BUILD_BASE_URL_DEVELOP="https://raw.githubusercontent.com/os2display/display-templates/develop/build/" \ - --env DEPLOYMENT_BUILD_BASE_URL_MAIN="https://raw.githubusercontent.com/os2display/display-templates/main/build/" \ - node yarn build -``` - -### Linting - -```bash -docker compose run --rm node yarn check-coding-standards -``` - -```bash -docker compose run --rm node yarn apply-coding-standards -``` - -### Tests - -Run tests - -```sh -# Templates -docker compose run --rm cypress run --component -# Screen layouts -docker compose run --rm cypress run -``` - -Or open mode - -```sh -yarn cypress open -``` diff --git a/docs/test.md b/docs/test.md index d0ed9808..165d91f5 100644 --- a/docs/test.md +++ b/docs/test.md @@ -1,6 +1,8 @@ # Test -## Playwright +## API tests - PHPUnit + +## Frontend tests - Playwright To test the React apps we use playwright. From bf957a3d9f7e8814858994088e15175fdeed874c Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Fri, 29 Aug 2025 14:09:27 +0200 Subject: [PATCH 02/19] 4565: Continued work on writing developer documentation --- README.md | 241 +++++++++++++++--- Taskfile.yml | 36 +++ UPGRADELOG.md | 11 + .../shared/grid-generator}/grid-generator.md | 0 docs/client/error-codes.md | 9 - docs/custom-templates.md | 46 ---- docs/readmes/client.md | 86 ------- docs/test.md | 59 ----- 8 files changed, 250 insertions(+), 238 deletions(-) create mode 100644 UPGRADELOG.md rename {docs/readmes => assets/shared/grid-generator}/grid-generator.md (100%) delete mode 100644 docs/client/error-codes.md delete mode 100644 docs/custom-templates.md delete mode 100644 docs/test.md diff --git a/README.md b/README.md index 7ca957e4..16ae1f98 100644 --- a/README.md +++ b/README.md @@ -3,22 +3,36 @@ ## Description The purpose of OS2Display is to deliver content to information screens. -At the core, is the API that clients can connect to. All data runs through this API. -The project also includes an Admin for creating content and a Client for displaying the content. +At the core of OS2Display is the API that clients communicate with. All data runs through this API. +It also includes an Admin for creating content and a Client for displaying the content. The system is browser-based. Further documentation can be found in the [https://os2display.github.io/display-docs/](https://os2display.github.io/display-docs/). +## ADR - Architectural Decision Records + +Architectural decisions are recorded in the `docs/adr` folder. + ## Technologies The API is written in PHP with Symfony and API Platform as frameworks. The Admin and Client are written in javascript and React. +## Versioning + +We use [SemVer](http://semver.org/) for versioning. +For the versions available, see the +[tags on this repository](https://github.com/os2display/display-api-service/tags). + ## Taskfile -The project ships with a [taskfile](https://taskfile.dev/) for executing common commands. +The project includes a [taskfile](https://taskfile.dev/) for executing common commands. + +See [https://taskfile.dev/docs/installation](https://taskfile.dev/docs/installation) for installation instructions. + +If you want to execute the commands without taskfile, look in `taskfile.yml` for the commands that are run. For a list of commands, run: @@ -34,21 +48,6 @@ To get started with the development setup, run the following task command: task site-install ``` -or without taskfile: - -```bash -docker compose pull -docker compose run --rm node npm install -docker compose up --detach -docker compose exec phpfpm composer install - -# Run migrations -docker compose exec phpfpm bin/console doctrine:migrations:migrate - -# Load fixtures (Optional) -docker compose exec phpfpm bin/console hautelook:fixtures:load --no-interaction -``` - The fixtures have an admin user: with the password: "apassword". The fixtures have an editor user: with the password: "apassword". @@ -64,11 +63,12 @@ APP_ENV=prod APP_SECRET= ``` -TODO: Add further instructions. +TODO: Add further production instructions: Build steps, release.json, ## Coding standards -Before a PR can be merged it has to pass the Github Actions checks. See `.github/workflows`. +Before a PR can be merged it has to pass the GitHub Actions checks. See `.github/workflows` for workflows that should +pass before a PR will be accepted. Run the coding standards checks: @@ -170,34 +170,59 @@ curl --location --request 'GET' \ --header 'Authorization: Bearer ' ``` -## Tests +## Test -### API tests +### API tests - PHPUnit Run automated tests for the API: ```shell -docker compose exec phpfpm composer test-setup -docker compose exec phpfpm composer test +task test:api ``` -Disable or hide deprecation warnings using the [`SYMFONY_DEPRECATIONS_HELPER` environment -variable](https://symfony.com/doc/current/components/phpunit_bridge.html#configuration), e.g. +### Frontend tests - Playwright + +To test the React apps we use playwright. + +#### Updating Playwright + +It is important that the versions of the playwright container and the library imported in package.json align. + +See the `docker-compose.override.yml` playwright entry and the version imported in package.json. + +#### Testing on the built files + +This project includes a test script that handles building assets, running +Playwright tests, and stops and starts the node container. This script tests the +*built* files. This is the approach the GitHub Action uses. ```shell -docker compose exec --env SYMFONY_DEPRECATIONS_HELPER=disabled phpfpm composer test +task test:frontend-built ``` -### Admin and Client tests +or + +```shell +./scripts/test {TEST-PATH} +``` + +TEST-PATH is optional, and is the specific test file or directory to run like +`admin`/`client`/`template` or a specific file, e.g. `admin-app.spec.js`. If +TEST-PATH is omitted, all tests will run. + +#### Testing on local machine -To run tests, use the script: +To run test from the local machine, there are a few options. ```shell -./scripts/test.sh +task test:frontend-local ``` -This script will stop the node container, build the javascript/css assets, and run tests with playwright, -and starts the node container again. +In interactive mode: + +```shell +task test:frontend-local-ui +``` ## API specification and generated code @@ -206,7 +231,7 @@ When the API is changed a new OpenAPI specification should be generated that ref To generate the updated API specification, run the following command: ```shell -docker compose exec phpfpm composer update-api-spec +task generate:api-spec ``` This will generate `public/api-spec-v2.json` and `public/api-spec-v2.yaml`. @@ -217,7 +242,7 @@ This generated API specification is used to generate To generate the Redux Toolkit RTK Query code, run the following command: ```shell -docker compose exec node npx @rtk-query/codegen-openapi /app/assets/shared/redux/openapi-config.js +task generate:redux-toolkit-api ``` This will generate `assets/shared/redux/generated-api.ts`. This generated code is enhanced by the custom file @@ -236,6 +261,84 @@ for information about the code generation. Configuration of the project should be added to `.env.local`. Default values are set in `.env`. +## Rest API & Relationships + +To avoid embedding all relations in REST representations but still allow the clients to minimize the amount of API calls +they have to make all endpoints that have relations also has a `relationsModified` field: + +```json + "@id": "/v2/screens/000XB4RQW418KK14AJ054W1FN2", + ... + "relationsModified": { + "campaigns": "cf9bb7d5fd04743dd21b5e3361db7eed575258e0", + "layout": "4dc925b9043b9d151607328ab2d022610583777f", + "regions": "278df93a0dc5309e0db357177352072d86da0d29", + "inScreenGroups": "bf0d49f6af71ac74da140e32243f3950219bb29c" + } +``` + +The checksums are based on `id`, `version` and `relationsModified` fields of the entity under that key in the +relationship tree. This ensures that any change in the bottom of the tree will propagate as changed checksums up the +tree. + +Updating `relationsModified` is handled in a `postFlush` event listener `App\EventListener\RelationsModifiedAtListener`. +The listener will execute a series of raw SQL statements starting from the bottom of the tree and progressing up. + +### Partial Class Diagram + +For reference a partial class diagram to illustrate the relevant relationships. + +```mermaid +classDiagram + class `Screen` + class `ScreenCampaign` + class `ScreenGroup` + class `ScreenGroupCampaign` + class `ScreenLayout` + class `ScreenLayoutRegions` + class `PlaylistScreenRegion` + class `Playlist` + class `Schedule` + class `PlaylistSlide` + class `Slide` + class `Template` + class `Theme` + class `Media` + class `Feed` + class `FeedSource` + Screen "1..*" -- "0..n" ScreenGroup + Screen "0..*" -- "1" ScreenLayout + Screen "1" -- "0..*" ScreenCampaign + ScreenLayout "1" -- "1..n" ScreenLayoutRegions + ScreenGroup "1" -- "1..n" ScreenGroupCampaign + Screen "1" -- "1..n" PlaylistScreenRegion + ScreenLayoutRegions "1" -- "1..n" PlaylistScreenRegion + ScreenCampaign "0..n" -- "1" Playlist + PlaylistScreenRegion "0..n" -- "1" Playlist + ScreenGroupCampaign "0..n" -- "1" Playlist + Playlist "1" -- "0..n" Schedule + Playlist "1" -- "0..n" PlaylistSlide + PlaylistSlide "0..n" -- "1" Slide + Slide "0..n" -- "1" Template + Slide "0..n" -- "1" Theme + Theme "0..n" -- "0..1" Media : Has logo + Slide "0..n" -- "0..n" Media : Has media + Slide "0..1" -- "0..1" Feed + Feed "0..n" -- "1" FeedSource +``` + +## Error codes in the Client + +The Client at `/client` can display the following error codes: + +* ER101: API returns 401. Token could not be refreshed. This could be caused by logging out in the admin. +* ER102: Token could not be refreshed in normal refresh token loop. +* ER103: Token refresh aborted, refresh token, iat and/or exp not set. +* ER104: Release file could not be loaded. +* ER105: Token is expired. +* ER106: Token is valid but should have been refreshed. +* ER201: Error loading slide template. + ## Preview mode in the Client The Client can be started in preview mode by setting the following url parameters: @@ -251,8 +354,70 @@ The preview will use the token and tenant for accessing the data from the api. This feature is used in the Admin for displaying previews of slides, playlists and screens. -## Versioning +## Custom Templates -We use [SemVer](http://semver.org/) for versioning. -For the versions available, see the -[tags on this repository](https://github.com/os2display/display-api-service/tags). +It is possible to include your own templates in your installation. + +### Location + +Custom templates should be placed in the folder `assets/shared/custom-templates/`. +This folder is in `.gitignore` so the contents will not be added to the git repository. + +How you populate this folder with your custom templates is up to you: + +* A git repository with root in the `assets/shared/custom-templates/` folder. +* A symlink from another folder. +* Maintaining a fork of the display repository. +* ... + +### Files + +The following files are required for a custom template: + +* `custom-template-name.jsx` - A javascript module for the template. +* `custom-template-name.json` - A configuration file for the template. + +Replace `custom-template-name` with a unique name for the template. + +#### custom-template-name.jsx + +The `.jsx` should expose the following functions: + +* id() - The ULID of the template. Generate a ULID for your custom template. +* config() - Should contain the following keys: id (as above), title (the titel displayed in the admin), options, + adminForm. +* renderSlide(slide, run, slideDone) - Should return the JSX for the template. + +For an example of a custom template see `assets/shared/custom-templates-example/`. + +### Contributing template + +If you think the template could be used by other, consider contributing the template to the project as a pull request. + +#### Guide for contributing templates + +* Fork the `os2display/display` repository. +* Move your custom template files (the .json and .jsx files and other required files) from the + `assets/shared/custom-templates/` folder to the `assets/shared/templates/` folder. +* Create a PR to `os2display/display` repository. + +### Psalm static analysis + +[Psalm](https://psalm.dev/) is used for static analysis. To run +Psalm do + +```shell +task code-analysis +``` + +We use [a baseline file](https://psalm.dev/docs/running_psalm/dealing_with_code_issues/#using-a-baseline-file) for Psalm +([`psalm-baseline.xml`](psalm-baseline.xml)). Run + +```shell +task psalm:update-baseline +``` + +to update the baseline file. + +Psalm [error level](https://psalm.dev/docs/running_psalm/error_levels/) is set +to level 2. diff --git a/Taskfile.yml b/Taskfile.yml index f0fd1574..4bc078f5 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -152,6 +152,11 @@ tasks: cmds: - task composer -- code-analysis + psalm:update-baseline: + desc: "Updates the Psalm baseline file" + cmds: + - task compose -- exec phpfpm vendor/bin/psalm --update-baseline + fixtures:load: prompt: "This will reset your content. Continue?" desc: Apply fixtures @@ -167,3 +172,34 @@ tasks: - task compose -- exec phpfpm bin/console doctrine:migrations:migrate --no-interaction - task compose-up silent: true + + test:api: + desc: "Runs API tests (PHPUnit)" + cmds: + - task composer -- test-setup + - task compose -- exec --env SYMFONY_DEPRECATIONS_HELPER=disabled phpfpm composer test + + test:frontend-built: + desc: "Runs frontend tests (Playwright) on the built files. This temporarily stops the node container" + cmds: + - ./scripts/test + + test:frontend-local: + desc: "Runs frontend tests from the local machine" + cmds: + - BASE_URL="https://display.local.itkdev.dk" npx playwright test + + test:frontend-local-ui: + desc: "Runs frontend tests from the local machine in UI mode" + cmds: + - BASE_URL="https://display.local.itkdev.dk" npx playwright test --ui + + generate:api-spec: + desc: "Generate the OpenAPI specifications (in public/) from the API Platform config" + cmds: + - task compose -- exec phpfpm composer update-api-spec + + generate:redux-toolkit-api: + desc: "Generate the RTK Query api slices (in assets/shared/redux/)" + cmds: + - task compose -- exec node npx @rtk-query/codegen-openapi /app/assets/shared/redux/openapi-config.js diff --git a/UPGRADELOG.md b/UPGRADELOG.md new file mode 100644 index 00000000..6e3cc768 --- /dev/null +++ b/UPGRADELOG.md @@ -0,0 +1,11 @@ +# Upgrade log + +## 2.x -> 3.0.0 + +1. Upgrade the API to the latest version of 2.x. +2. Add the following environment variables to `.env.local`: + + These values were previously added to admin|client: `/public/config.json`. + See `README.md` for configuration options. +3. Run doctrine migrate +4. diff --git a/docs/readmes/grid-generator.md b/assets/shared/grid-generator/grid-generator.md similarity index 100% rename from docs/readmes/grid-generator.md rename to assets/shared/grid-generator/grid-generator.md diff --git a/docs/client/error-codes.md b/docs/client/error-codes.md deleted file mode 100644 index 2c906b67..00000000 --- a/docs/client/error-codes.md +++ /dev/null @@ -1,9 +0,0 @@ -# Error codes - -* ER101: API returns 401. Token could not be refreshed. This could be caused by logging out in the admin. -* ER102: Token could not be refreshed in normal refresh token loop. -* ER103: Token refresh aborted, refresh token, iat and/or exp not set. -* ER104: Release file could not be loaded. -* ER105: Token is expired. -* ER106: Token is valid but should have been refreshed. -* ER201: Error loading slide template. diff --git a/docs/custom-templates.md b/docs/custom-templates.md deleted file mode 100644 index 5d5fbf03..00000000 --- a/docs/custom-templates.md +++ /dev/null @@ -1,46 +0,0 @@ -# Custom Templates - -It is possible to include your own templates in your installation. - -## Location - -Custom templates should be placed in the folder `assets/shared/custom-templates/`. -This folder is in `.gitignore` so the contents will not be added to the git repository. - -How you populate this folder with your custom templates is up to you: - -* A git repository with root in the `assets/shared/custom-templates/` folder. -* A symlink from another folder. -* Maintaining a fork of the display repository. -* ... - -## Files - -The following files are required for a custom template: - -* `custom-template-name.jsx` - A javascript module for the template. -* `custom-template-name.json` - A configuration file for the template. - -Replace `custom-template-name` with a unique name for the template. - -### custom-template-name.jsx - -The `.jsx` should expose the following functions: - -* id() - The ULID of the template. Generate a ULID for your custom template. -* config() - Should contain the following keys: id (as above), title (the titel displayed in the admin), options, - adminForm. -* renderSlide(slide, run, slideDone) - Should return the JSX for the template. - -For an example of a custom template see `assets/shared/custom-templates-example/`. - -## Contributing template - -If you think the template could be used by other, consider contributing the template to the project as a pull request. - -### Guide for contributing template - -* Fork the `os2display/display` repository. -* Move your custom template files (the .json and .jsx files and other required files) from the - `assets/shared/custom-templates/` folder to the `assets/shared/templates/` folder. -* Create a PR to `os2display/display` repository. diff --git a/docs/readmes/client.md b/docs/readmes/client.md index 0551f3cd..c358b10a 100644 --- a/docs/readmes/client.md +++ b/docs/readmes/client.md @@ -34,89 +34,3 @@ invisible. All endpoint should be configured without a trailing slash. The endpoints `apiEndpoint` can be left empty if the api is hosted from the root of the same domain as the client. E.g. if the api is at and the client is at - -## Preview - -The client can be started in preview mode by setting the following url parameters: - -```text -preview= -preview-id= -preview-token= -preview-tenant= -``` - -The preview will use the token and tenant for accessing the data from the api. - -## Docker development setup - -Start docker setup - -```shell -# Install npm packages -docker compose run --rm node yarn install - -# Up the containers -docker compose up -d - -# Optional: Follow the node logs to see when the code is compiled. -docker compose logs -f node -``` - -The display client is here: `http://display-client.local.itkdev.dk/`. - -The code is compiled when changed. - -The client can be configured by creating `public/config.json` with relevant values. -See `public/example_config.json` for values. - -The client should have `public/release.json` with relevant values. -See `public/example_release.json` for values. - -## Coding standards - -For code analysis we use the [Airbnb style guide for javascript](https://github.com/airbnb/javascript) and for -formatting we use [Prettier](https://github.com/prettier/prettier). - -```shell -# Check for coding standards issues -docker compose exec node bash -c 'yarn check-coding-standards' - -# Auto-correct coding standards issues -docker compose exec node bash -c 'yarn apply-coding-standards' -``` - -## Testing with cypress - -We use [cypress](https://www.cypress.io/) for testing. - -To run cypress tests in the cypress container: - -```shell -docker compose run cypress run -``` - -## Build for production - -Github actions will build both docker images published to -[docker hub](https://hub.docker.com/repository/docker/os2display/display-client/general) and release assets published -as [github releases](https://github.com/os2display/display-client/releases). -To run the display client choose which option suits you and download it. - -If you wish to do your own production build, you need to do - -```shell -docker compose run node yarn install -docker compose run node yarn build - -# Make release file. Replace 'x.y.z' with relevant release version -printf "{\n \"releaseTimestamp\": $(date +%s),\n \"releaseTime\": \"$(date)\",\n \"releaseVersion\": \"x.y.z\"\n}" > build/release.json - -# Make config file -cp public/example_config.json build/config.json -``` - -This will build the client configured to be hosted at `/client`. If you wish to host at a different path -you need to edit `homepage` in `package.json` and re-build. - -For instructions on how to host a complete OS2display setup please see the [docs](https://os2display.github.io/display-docs/). diff --git a/docs/test.md b/docs/test.md deleted file mode 100644 index 165d91f5..00000000 --- a/docs/test.md +++ /dev/null @@ -1,59 +0,0 @@ -# Test - -## API tests - PHPUnit - -## Frontend tests - Playwright - -To test the React apps we use playwright. - -### Updating Playwright - -It is important that the versions of the playwright container and the library imported in package.json align. - -See the `docker-compose.override.yml` playwright entry and the version imported in package.json. - -### Dev mode - -This project includes a test script that handles building assets, running -Playwright tests, and stops and starts the node container. This script tests the -*built* files. - -```bash -./scripts/test {TEST-PATH} -``` - -TEST-PATH is optional, and is the specific test file or directory to run like -`admin`/`client`/`template` or a specific file, e.g. `admin-app.spec.js`. If -TEST-PATH is omitted, all tests will run. - -To run tests locally, there are a few options. - -To run from the developer machine: - -```shell -BASE_URL="https://display.local.itkdev.dk" npx playwright test template -``` - -In interactive mode: - -```shell -BASE_URL="https://display.local.itkdev.dk" npx playwright test template --ui -``` - -### Prod mode - -Another option is to run the tests on the built javascript assets through the playwright container. -This is the option that runs in Github Actions. - -```shell -# Stop the node container, to avoid Vite build dev assets. -docker compose stop node - -# Build the assets -docker compose run --rm node npm run build - -# Run the test -docker compose run --rm playwright npx playwright test - -# To return to vite dev mode, restart the node container. -``` From a27e7b1e831045335603c683130c956ac8935d7a Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Fri, 29 Aug 2025 14:35:31 +0200 Subject: [PATCH 03/19] 4565: Applied coding standards --- README.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 16ae1f98..c4c089cd 100644 --- a/README.md +++ b/README.md @@ -331,13 +331,13 @@ classDiagram The Client at `/client` can display the following error codes: -* ER101: API returns 401. Token could not be refreshed. This could be caused by logging out in the admin. -* ER102: Token could not be refreshed in normal refresh token loop. -* ER103: Token refresh aborted, refresh token, iat and/or exp not set. -* ER104: Release file could not be loaded. -* ER105: Token is expired. -* ER106: Token is valid but should have been refreshed. -* ER201: Error loading slide template. +- ER101: API returns 401. Token could not be refreshed. This could be caused by logging out in the admin. +- ER102: Token could not be refreshed in normal refresh token loop. +- ER103: Token refresh aborted, refresh token, iat and/or exp not set. +- ER104: Release file could not be loaded. +- ER105: Token is expired. +- ER106: Token is valid but should have been refreshed. +- ER201: Error loading slide template. ## Preview mode in the Client @@ -365,17 +365,17 @@ This folder is in `.gitignore` so the contents will not be added to the git repo How you populate this folder with your custom templates is up to you: -* A git repository with root in the `assets/shared/custom-templates/` folder. -* A symlink from another folder. -* Maintaining a fork of the display repository. -* ... +- A git repository with root in the `assets/shared/custom-templates/` folder. +- A symlink from another folder. +- Maintaining a fork of the display repository. +- ... ### Files The following files are required for a custom template: -* `custom-template-name.jsx` - A javascript module for the template. -* `custom-template-name.json` - A configuration file for the template. +- `custom-template-name.jsx` - A javascript module for the template. +- `custom-template-name.json` - A configuration file for the template. Replace `custom-template-name` with a unique name for the template. @@ -383,10 +383,10 @@ Replace `custom-template-name` with a unique name for the template. The `.jsx` should expose the following functions: -* id() - The ULID of the template. Generate a ULID for your custom template. -* config() - Should contain the following keys: id (as above), title (the titel displayed in the admin), options, +- id() - The ULID of the template. Generate a ULID for your custom template. +- config() - Should contain the following keys: id (as above), title (the titel displayed in the admin), options, adminForm. -* renderSlide(slide, run, slideDone) - Should return the JSX for the template. +- renderSlide(slide, run, slideDone) - Should return the JSX for the template. For an example of a custom template see `assets/shared/custom-templates-example/`. @@ -396,10 +396,10 @@ If you think the template could be used by other, consider contributing the temp #### Guide for contributing templates -* Fork the `os2display/display` repository. -* Move your custom template files (the .json and .jsx files and other required files) from the +- Fork the `os2display/display` repository. +- Move your custom template files (the .json and .jsx files and other required files) from the `assets/shared/custom-templates/` folder to the `assets/shared/templates/` folder. -* Create a PR to `os2display/display` repository. +- Create a PR to `os2display/display` repository. ### Psalm static analysis From 3eab583f25cfbe9192a94069850ab5299847254d Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Fri, 29 Aug 2025 14:38:16 +0200 Subject: [PATCH 04/19] 4565: Cleanup --- README.md | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c4c089cd..8c6f80e1 100644 --- a/README.md +++ b/README.md @@ -401,23 +401,21 @@ If you think the template could be used by other, consider contributing the temp `assets/shared/custom-templates/` folder to the `assets/shared/templates/` folder. - Create a PR to `os2display/display` repository. -### Psalm static analysis +### Static analysis -[Psalm](https://psalm.dev/) is used for static analysis. To run -Psalm do +[Psalm](https://psalm.dev/) is used for static analysis: ```shell task code-analysis ``` We use [a baseline file](https://psalm.dev/docs/running_psalm/dealing_with_code_issues/#using-a-baseline-file) for Psalm -([`psalm-baseline.xml`](psalm-baseline.xml)). Run +([`psalm-baseline.xml`](psalm-baseline.xml)). + +Run this command to update the baseline file: ```shell task psalm:update-baseline ``` -to update the baseline file. - -Psalm [error level](https://psalm.dev/docs/running_psalm/error_levels/) is set -to level 2. +Psalm [error level](https://psalm.dev/docs/running_psalm/error_levels/) is set to level 2. From 839a9079ca69122060116a89ccf347a7b6461528 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Sat, 30 Aug 2025 08:34:44 +0200 Subject: [PATCH 05/19] 4565: Added documentation for admin and client configuration --- .env | 33 ++- README.md | 101 ++++++++ assets/admin/components/user/login.jsx | 8 +- docs/readmes/api.md | 326 ------------------------- docs/readmes/client.md | 36 --- 5 files changed, 118 insertions(+), 386 deletions(-) delete mode 100644 docs/readmes/api.md delete mode 100644 docs/readmes/client.md diff --git a/.env b/.env index ab0e35b3..93e617a9 100644 --- a/.env +++ b/.env @@ -39,13 +39,6 @@ CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$' # CORS_ALLOW_ORIGIN="^.*" ###< nelmio/cors-bundle ### -###> App ### -APP_DEFAULT_DATE_FORMAT='Y-m-d\TH:i:s.v\Z' -APP_ACTIVATION_CODE_EXPIRE_INTERNAL=P2D -APP_KEY_VAULT_SOURCE=ENVIRONMENT -APP_KEY_VAULT_JSON="{}" -###< App ### - ###> lexik/jwt-authentication-bundle ### JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem @@ -63,6 +56,21 @@ JWT_REFRESH_TOKEN_TTL=7200 JWT_SCREEN_REFRESH_TOKEN_TTL=2592000 ###< gesdinet/jwt-refresh-token-bundle ### +###> redis ### +REDIS_CACHE_PREFIX=DisplayApiService +REDIS_CACHE_DSN=redis://redis:6379/0 +###< redis ### + +###> App ### +APP_DEFAULT_DATE_FORMAT='Y-m-d\TH:i:s.v\Z' +APP_ACTIVATION_CODE_EXPIRE_INTERNAL=P2D +APP_KEY_VAULT_SOURCE=ENVIRONMENT +APP_KEY_VAULT_JSON="{}" +EVENTDATABASE_API_V2_CACHE_EXPIRE_SECONDS=300 +TRACK_SCREEN_INFO=false +TRACK_SCREEN_INFO_UPDATE_INTERVAL_SECONDS=300 +###< App ### + ###> itk-dev/openid-connect-bundle ### # internal provider INTERNAL_OIDC_METADATA_URL=INTERNAL_OIDC_METADATA_URL @@ -82,17 +90,11 @@ EXTERNAL_OIDC_REDIRECT_URI=EXTERNAL_OIDC_REDIRECT_URI EXTERNAL_OIDC_LEEWAY=30 EXTERNAL_OIDC_HASH_SALT= EXTERNAL_OIDC_CLAIM_ID=signinname -###< itk-dev/openid-connect-bundle ### # cli redirect url OIDC_CLI_REDIRECT=APP_CLI_REDIRECT_URI ###< itk-dev/openid-connect-bundle ### -###> redis ### -REDIS_CACHE_PREFIX=DisplayApiService -REDIS_CACHE_DSN=redis://redis:6379/0 -###< redis ### - ###> Calendar Api Feed Source ### # See docs/feed/calendar-api-feed.md for variable explainations. CALENDAR_API_FEED_SOURCE_LOCATION_ENDPOINT= @@ -105,11 +107,6 @@ CALENDAR_API_FEED_SOURCE_DATE_TIMEZONE= CALENDAR_API_FEED_SOURCE_CACHE_EXPIRE_SECONDS=300 ###< Calendar Api Feed Source ### -EVENTDATABASE_API_V2_CACHE_EXPIRE_SECONDS=300 - -TRACK_SCREEN_INFO=false -TRACK_SCREEN_INFO_UPDATE_INTERVAL_SECONDS=300 - ###> Admin configuration ### ### Will be injected in the html of the admin page. ADMIN_REJSEPLANEN_APIKEY= diff --git a/README.md b/README.md index 8c6f80e1..40e05ebb 100644 --- a/README.md +++ b/README.md @@ -261,6 +261,107 @@ for information about the code generation. Configuration of the project should be added to `.env.local`. Default values are set in `.env`. +### Admin configuration + +Will be exposed through the `/config/admin` route. + +```dotenv +###> Admin configuration ### +### Will be exposed through the /config/admin route. +ADMIN_REJSEPLANEN_APIKEY= +ADMIN_SHOW_SCREEN_STATUS=false +ADMIN_TOUCH_BUTTON_REGIONS=false +ADMIN_LOGIN_METHODS='[{"type":"username-password","enabled":true,"provider":"username-password","label":""}]' +ADMIN_ENHANCED_PREVIEW=false +###< Admin configuration ### +``` + +* ADMIN_REJSEPLANEN_APIKEY: An API key accessing Rejseplanen API used for Travel template. + See [https://labs.rejseplanen.dk/](https://labs.rejseplanen.dk/) for information about acquiring an API key. + + **Default**: Not set. +* ADMIN_SHOW_SCREEN_STATUS: Should the status of the screen be shown in the Admin (true|false)? + + **Default**: Disabled. +* ADMIN_TOUCH_BUTTON_REGIONS: Should the option of setting a button name for a slide be enabled in the Admin? + This option is used by the Client if a region is configured to be a "touch-buttons" region. + + **Default**: Disabled. +* ADMIN_LOGIN_METHODS: Which login methods should be displayed in the admin (array of objects as json string)? + + Available types: "oidc" | "username-password". + ```json + { + "type": "oidc", + "provider": "internal", + "label": "Button text", + "icon": "faCity" + } + ``` + - provider: "internal" | "external". See "OIDC providers" for a description of OIDC providers. + - label: Button text. Defaults to "Ekstern" for "external" provider and "Medarbejder" for "internal" provider. + - icon: Name of the fontawesome icon to use for the button or "mitID" for MitID logo. + ```json + { + "type": "username-password", + "provider": "username-password", + "label": "" + } + ``` + - provider: "username-password" + - label: Label for the username password login section + + **Default**: Username and password login option is enabled. +* ADMIN_ENHANCED_PREVIEW: Should the enhanced preview mode be active (true|false)? When enabled, previews will be + handled by iFraming in the Client app. This will allow the option of previewing playlists and screens. + If disabled, only slides can be previewed. This will be with the "live" method. This preview is not as precise. + + **Default**: Disabled. + +### Client configuration + +Will be exposed through the `/config/client` route. + +```dotenv +###> Client configuration ### +CLIENT_LOGIN_CHECK_TIMEOUT=20000 +CLIENT_REFRESH_TOKEN_TIMEOUT=300000 +CLIENT_RELEASE_TIMESTAMP_INTERVAL_TIMEOUT=600000 +CLIENT_SCHEDULING_INTERVAL=60000 +CLIENT_PULL_STRATEGY_INTERVAL=90000 +CLIENT_COLOR_SCHEME='{"type":"library","lat":56.0,"lng":10.0}' +CLIENT_DEBUG=false +###< Client configuration ### +``` + +* CLIENT_LOGIN_CHECK_TIMEOUT: How often (milliseconds) should the screen check for status when it is not logged in, and + waiting for being activated in the administration. + + **Default**: 20 s. +* CLIENT_REFRESH_TOKEN_TIMEOUT: How often (milliseconds) should it be checked whether the token needs to be refreshed? + + **Default**: 30 s. +* CLIENT_REFRESH_TOKEN_TIMEOUT: How often (milliseconds) should it be checked whether the token needs to be refreshed? + + **Default**: 60 s. +* CLIENT_SCHEDULING_INTERVAL: How often (milliseconds) should the scheduling be run for the logged in screen? + + **Default**: 60 s. +* CLIENT_PULL_STRATEGY_INTERVAL: How often (milliseconds) should data be pulled from the API? + + **Default**: 1 m. and 30 s. +* CLIENT_COLOR_SCHEME: Which colour scheme should be enabled? Should be a json object as string. + This is used to signal how changes to darkmode are handled. + Options are: + * Not set - will use the browsers prefers-color-scheme setting. + * '{"type":"library","lat":56.0,"lng":10.0}' - In this case the change to darkmode is handled with a library that + activates darkmode according to sunrise/sunset of the location given by the longitude/latitude (lat/lng). + + **Default**: Library mode with a lat/lng set in Denmark. +* CLIENT_DEBUG: Should the Client be in debug mode (true|false). When not in debug mode the mouse pointer is hidden. + + **Default**: Disabled. + ## Rest API & Relationships To avoid embedding all relations in REST representations but still allow the clients to minimize the amount of API calls diff --git a/assets/admin/components/user/login.jsx b/assets/admin/components/user/login.jsx index c79dc03c..7ab759d6 100644 --- a/assets/admin/components/user/login.jsx +++ b/assets/admin/components/user/login.jsx @@ -195,20 +195,17 @@ function Login() { { type: "oidc", provider: "internal", - enabled: true, label: null, icon: null, }, { type: "oidc", provider: "external", - enabled: true, label: null, icon: null, }, { type: "username-password", - enabled: true, label: null, icon: null, }, @@ -268,11 +265,10 @@ function Login() { }, [search]); const oidcLogins = loginMethods.filter( - (loginMethod) => loginMethod.enabled && loginMethod.type === "oidc", + (loginMethod) => loginMethod.type === "oidc", ); const usernamePasswordLogins = loginMethods.filter( - (loginMethod) => - loginMethod.enabled && loginMethod.type === "username-password", + (loginMethod) => loginMethod.type === "username-password", ); return ( diff --git a/docs/readmes/api.md b/docs/readmes/api.md deleted file mode 100644 index e2d82128..00000000 --- a/docs/readmes/api.md +++ /dev/null @@ -1,326 +0,0 @@ -# DisplayApi - -## OpenAPI specification - -The OpenAPI specification is committed to this repo as `public/api-spec-v2.yaml` -and as `public/api-spec-v2.json`. - -A CI check will compare the current API implementation to the spec. If they -are different the check will fail. - -If a PR makes _planned_ changes to the spec, the commited file must be updated: - -```shell -docker compose exec phpfpm composer update-api-spec -``` - -If these are _breaking_ changes the API version must be changed accordingly. - -## Stateless - -The API is stateless except `/v2/authentication` routes. -Make sure to set the `CORS_ALLOW_ORIGIN` correctly in `.env.local`. - -## Rest API & Relationships - -To avoid embedding all relations in REST representations but still allow the clients to minimize the amount of API calls -they have to make all endpoints that have relations also has a `relationsModified` field: - -```json - "@id": "/v2/screens/000XB4RQW418KK14AJ054W1FN2", - ... - "relationsModified": { - "campaigns": "cf9bb7d5fd04743dd21b5e3361db7eed575258e0", - "layout": "4dc925b9043b9d151607328ab2d022610583777f", - "regions": "278df93a0dc5309e0db357177352072d86da0d29", - "inScreenGroups": "bf0d49f6af71ac74da140e32243f3950219bb29c" - } -``` - -The checksums are based on `id`, `version` and `relationsModified` fields of the entity under that key in the -relationship tree. This ensures that any change in the bottom of the tree will propagate as changed checksums up the -tree. - -Updating `relationsModified` is handled in a `postFlush` event listener `App\EventListener\RelationsModifiedAtListener`. -The listener will execute a series of raw SQL statements starting from the bottom of the tree and progressing up. - -### Partial Class Diagram - -For reference a partial class diagram to illustrate the relevant relationships. - -```mermaid -classDiagram - class `Screen` - class `ScreenCampaign` - class `ScreenGroup` - class `ScreenGroupCampaign` - class `ScreenLayout` - class `ScreenLayoutRegions` - class `PlaylistScreenRegion` - class `Playlist` - class `Schedule` - class `PlaylistSlide` - class `Slide` - class `Template` - class `Theme` - class `Media` - class `Feed` - class `FeedSource` - Screen "1..*" -- "0..n" ScreenGroup - Screen "0..*" -- "1" ScreenLayout - Screen "1" -- "0..*" ScreenCampaign - ScreenLayout "1" -- "1..n" ScreenLayoutRegions - ScreenGroup "1" -- "1..n" ScreenGroupCampaign - Screen "1" -- "1..n" PlaylistScreenRegion - ScreenLayoutRegions "1" -- "1..n" PlaylistScreenRegion - ScreenCampaign "0..n" -- "1" Playlist - PlaylistScreenRegion "0..n" -- "1" Playlist - ScreenGroupCampaign "0..n" -- "1" Playlist - Playlist "1" -- "0..n" Schedule - Playlist "1" -- "0..n" PlaylistSlide - PlaylistSlide "0..n" -- "1" Slide - Slide "0..n" -- "1" Template - Slide "0..n" -- "1" Theme - Theme "0..n" -- "0..1" Media : Has logo - Slide "0..n" -- "0..n" Media : Has media - Slide "0..1" -- "0..1" Feed - Feed "0..n" -- "1" FeedSource -``` - -## Development Setup - -A `docker-compose.yml` file with a PHP 8.3 image is included in this project. -To install the dependencies you can run - -```shell -docker compose pull -docker compose up --detach -docker compose exec phpfpm composer install - -# Run migrations -docker compose exec phpfpm bin/console doctrine:migrations:migrate - -# Load fixtures (Optional) -docker compose exec phpfpm bin/console hautelook:fixtures:load --no-interaction -``` - -The fixtures have an admin user: with the password: apassword -The fixtures have an editor user: with the password: apassword -The fixtures have the image-text template, and two screen layouts: -full screen and "two boxes". - -## OIDC providers - -At the present two possible oidc providers are implemented: 'internal' and 'external'. -These work differently. - -The internal provider is expected to handle both authentication and authorization. -Any users logging in through the internal will be granted access based on the -tenants/roles provided. - -The external provider only handles authentication. A user logging in through the -external provider will not be granted access automatically, but will be challenged -to enter an activation (invite) code to verify access. - -### Internal - -The internal oidc provider gets that user's name, email and tenants from claims. - -The claim keys needed are set in the env variables: - -- `INTERNAL_OIDC_CLAIM_NAME` -- `INTERNAL_OIDC_CLAIM_EMAIL` -- `INTERNAL_OIDC_CLAIM_GROUPS` - -The value of the claim with the name that is defined in the env variable `INTERNAL_OIDC_CLAIM_GROUPS` is mapped to -the user's access to tenants in `App\Security\AzureOidcAuthenticator`. The claim field should consist of an array of -names that should follow the following structure ``. -`` can be `Admin` or `Redaktoer` (editor). -E.g. `Example1Admin` will map to the tenant with name `Example1` with `ROLE_ADMIN`. -If the tenant does not exist it will be created when the user logs in. - -### External - -The external oidc provider takes only the claim defined in the env variable -OIDC_EXTERNAL_CLAIM_ID, hashes it and uses this hash as providerId for the user. -When a user logs in with this provider, it is initially not in any tenant. -To be added to a tenant the user has to use an activation code a -ROLE_EXTERNAL_USER_ADMIN has created. - -## JWT Auth - -To authenticate against the API locally you must generate a private/public key pair: - -```shell -docker compose exec phpfpm bin/console lexik:jwt:generate-keypair -``` - -Then create a local test user if needed: - -```shell -docker compose exec phpfpm bin/console app:user:add -``` - -You can now obtain a token by sending a `POST` request to the -`/v2/authentication/token` endpoint: - -```curl -curl --location --request 'POST' \ - 'http://displayapiservice.local.itkdev.dk/v2/authentication/token' \ - --header 'accept: application/json' \ - --header 'Content-Type: application/json' \ - --data '{ - "email": "editor@example.com", - "password": "apassword" -}' -``` - -Either on the command line or through the OpenApi docs at `/docs` - -You can use the token either by clicking "Authorize" in the docs and entering - -```curl -Bearer -``` - -as the api key value. Or by adding an auth header to your requests - -```curl -curl --location --request 'GET' \ - 'http://displayapiservice.local.itkdev.dk/v2/layouts?page=1&itemsPerPage=10' \ - --header 'accept: application/ld+json' \ - --header 'Authorization: Bearer ' -``` - -### Psalm static analysis - -[Psalm](https://psalm.dev/) is used for static analysis. To run -Psalm do - -```shell -docker compose exec phpfpm composer install -docker compose exec phpfpm vendor/bin/psalm -``` - -We use [a baseline file](https://psalm.dev/docs/running_psalm/dealing_with_code_issues/#using-a-baseline-file) for Psalm -([`psalm-baseline.xml`](psalm-baseline.xml)). Run - -```shell -docker compose exec phpfpm vendor/bin/psalm --update-baseline -``` - -to update the baseline file. - -Psalm [error level](https://psalm.dev/docs/running_psalm/error_levels/) is set -to level 2. - -### Composer normalizer - -[Composer normalize](https://github.com/ergebnis/composer-normalize) is used for -formatting `composer.json` - -```shell -docker compose exec phpfpm composer normalize -``` - -### Tests - -Initialize test database: - -``` shell -docker compose exec phpfpm composer test-setup -``` - -Run tests: - -```shell -docker compose exec phpfpm composer test -``` - -A limited number of tests can be run by passing command line parameters to the command. - -By file - -```shell -docker compose exec phpfpm composer test tests/Api/UserTest.php -``` - -or by filtering to one method in the file - -```shell -docker compose exec phpfpm composer test tests/Api/UserTest.php --filter testExternalUserFlow -``` - -### Check Coding Standard - -The following command let you test that the code follows -the coding standard for the project. - -- PHP files [PHP Coding Standards Fixer](https://cs.symfony.com/) - -```shell -docker compose exec phpfpm composer coding-standards-check -``` - -- Markdown files (markdownlint standard rules) - -```shell -docker run --rm -v .:/app --workdir=/app node:20 npm install -docker run --rm -v .:/app --workdir=/app node:20 npm run coding-standards-check -``` - -#### YAML - -```sh -docker run --volume ${PWD}:/code --rm pipelinecomponents/yamllint yamllint config/api_platform -``` - -### Apply Coding Standards - -To attempt to automatically fix coding style issues - -- PHP files [PHP Coding Standards Fixer](https://cs.symfony.com/) - -```sh -docker compose exec phpfpm composer coding-standards-apply -``` - -- Markdown files (markdownlint standard rules) - -```shell -docker run --rm -v .:/app --workdir=/app node:18 npm install -docker run --rm -v .:/app --workdir=/app node:18 npm run coding-standards-apply -``` - -## Tests - -Run automated tests: - -```shell -docker compose exec phpfpm composer test setup -docker compose exec phpfpm composer test -``` - -Disable or hide deprecation warnings using the [`SYMFONY_DEPRECATIONS_HELPER` environment -variable](https://symfony.com/doc/current/components/phpunit_bridge.html#configuration), e.g. - -```shell -docker compose exec --env SYMFONY_DEPRECATIONS_HELPER=disabled phpfpm composer tests -``` - -## CI - -Github Actions are used to run the test suite and code style checks on all PRs. - -If you wish to test against the jobs locally you can install [act](https://github.com/nektos/act). -Then do: - -```shell -act -P ubuntu-latest=shivammathur/node:latest pull_request -``` - -## Versioning - -We use [SemVer](http://semver.org/) for versioning. -For the versions available, see the -[tags on this repository](https://github.com/os2display/display-api-service/tags). diff --git a/docs/readmes/client.md b/docs/readmes/client.md deleted file mode 100644 index c358b10a..00000000 --- a/docs/readmes/client.md +++ /dev/null @@ -1,36 +0,0 @@ -# Client - -This is the client that will display slides from OS2Display. -See -[https://github.com/os2display/display-docs/blob/main/client.md](https://github.com/os2display/display-docs/blob/main/client.md) -for more info about the client. - -## Config - -The client can be configured by creating `public/config.json` with relevant values. -See `public/example_config.json` for example values. - -Values explained: - -* apiEndpoint - The endpoint where the API is located. -* loginCheckTimeout - How often (milliseconds) should the screen check for -status when it is not logged in, and waiting for being activated in the -administration. -* configFetchInterval - How often (milliseconds) should a fresh -config.json be fetched. -* refreshTokenTimeout - How often (milliseconds) should it be checked -whether the token needs to be refreshed? -* releaseTimestampIntervalTimeout - How often (milliseconds) should the -code check if a new release has been deployed, and reload if true? -* dataStrategy.config.interval - How often (milliseconds) should data be fetched -for the logged in screen? -* colorScheme.lat - Where is the screen located? Used for darkmode. -* colorScheme.lng - Where is the screen located? Used for darkmode. -* schedulingInterval - How often (milliseconds) should scheduling for the -screen be checked. -* debug - Should the screen be in debug mode? If true, the cursor will be -invisible. - -All endpoint should be configured without a trailing slash. The endpoints `apiEndpoint` can be -left empty if the api is hosted from the root of the same domain as the client. E.g. if the api is at - and the client is at From ffed69e6968325963c3ac2f297cc60afdb2ab8fb Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Sat, 30 Aug 2025 08:53:03 +0200 Subject: [PATCH 06/19] 4565: Added table of contents --- README.md | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 40e05ebb..1374905d 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,37 @@ # OS2Display +## Table of Contents + +1. [Description](#description) +2. [ADR - Architectural Decision Records](#adr---architectural-decision-records) +3. [Technologies](#technologies) +4. [Versioning](#versioning) +5. [Taskfile](#taskfile) +6. [Development setup](#development-setup) +7. [Production setup](#production-setup) +8. [Coding standards](#coding-standards) +9. [Stateless](#stateless) +10. [OIDC providers](#oidc-providers) +11. [JWT Auth](#jwt-auth) +12. [Test](#test) +13. [API specification and generated code](#api-specification-and-generated-code) +14. [Configuration](#configuration) +15. [Rest API & Relationships](#rest-api--relationships) +16. [Error codes in the Client](#error-codes-in-the-client) +17. [Preview mode in the Client](#preview-mode-in-the-client) +18. [Custom Templates](#custom-templates) + ## Description -The purpose of OS2Display is to deliver content to information screens. -At the core of OS2Display is the API that clients communicate with. All data runs through this API. -It also includes an Admin for creating content and a Client for displaying the content. -The system is browser-based. +OS2Display is a browser-based system for delivering content to information screens. + +At the core of OS2Display is an API that clients communicate with. All data runs through this API. + +It includes an Admin for creating content and a Client for displaying the content. + +The structure is that slides are the content element of the system. Each slide is based on a template with content +added. The slides are gathered into a playlist. Playlists are then added to screens. +A screen is the connection between a physical device and the content. Further documentation can be found in the [https://os2display.github.io/display-docs/](https://os2display.github.io/display-docs/). @@ -42,6 +68,8 @@ task --list-all ## Development setup +Before first setup a JWT Auth keypair should be generated. See [JWT Auth](#jwt-auth). + To get started with the development setup, run the following task command: ```bash @@ -56,6 +84,8 @@ The fixtures have the image-text template, and two screen layouts: full screen a ## Production setup +A JWT Auth keypair should be generated. See [JWT Auth](#jwt-auth). + In `.env.local` set the following values: ```text @@ -315,6 +345,7 @@ ADMIN_ENHANCED_PREVIEW=false * ADMIN_ENHANCED_PREVIEW: Should the enhanced preview mode be active (true|false)? When enabled, previews will be handled by iFraming in the Client app. This will allow the option of previewing playlists and screens. If disabled, only slides can be previewed. This will be with the "live" method. This preview is not as precise. + See [Preview mode in the Client](#preview-mode-in-the-client). **Default**: Disabled. From c15ff6241dc631c0098976ed5133ba217cf726bd Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Sat, 30 Aug 2025 08:57:33 +0200 Subject: [PATCH 07/19] 4565: Applied coding standards --- README.md | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 1374905d..45170c31 100644 --- a/README.md +++ b/README.md @@ -306,20 +306,21 @@ ADMIN_ENHANCED_PREVIEW=false ###< Admin configuration ### ``` -* ADMIN_REJSEPLANEN_APIKEY: An API key accessing Rejseplanen API used for Travel template. +- ADMIN_REJSEPLANEN_APIKEY: An API key accessing Rejseplanen API used for Travel template. See [https://labs.rejseplanen.dk/](https://labs.rejseplanen.dk/) for information about acquiring an API key. **Default**: Not set. -* ADMIN_SHOW_SCREEN_STATUS: Should the status of the screen be shown in the Admin (true|false)? +- ADMIN_SHOW_SCREEN_STATUS: Should the status of the screen be shown in the Admin (true|false)? **Default**: Disabled. -* ADMIN_TOUCH_BUTTON_REGIONS: Should the option of setting a button name for a slide be enabled in the Admin? +- ADMIN_TOUCH_BUTTON_REGIONS: Should the option of setting a button name for a slide be enabled in the Admin? This option is used by the Client if a region is configured to be a "touch-buttons" region. **Default**: Disabled. -* ADMIN_LOGIN_METHODS: Which login methods should be displayed in the admin (array of objects as json string)? +- ADMIN_LOGIN_METHODS: Which login methods should be displayed in the admin (array of objects as json string)? Available types: "oidc" | "username-password". + ```json { "type": "oidc", @@ -328,9 +329,11 @@ ADMIN_ENHANCED_PREVIEW=false "icon": "faCity" } ``` + - provider: "internal" | "external". See "OIDC providers" for a description of OIDC providers. - label: Button text. Defaults to "Ekstern" for "external" provider and "Medarbejder" for "internal" provider. - icon: Name of the fontawesome icon to use for the button or "mitID" for MitID logo. + ```json { "type": "username-password", @@ -338,11 +341,12 @@ ADMIN_ENHANCED_PREVIEW=false "label": "" } ``` + - provider: "username-password" - label: Label for the username password login section **Default**: Username and password login option is enabled. -* ADMIN_ENHANCED_PREVIEW: Should the enhanced preview mode be active (true|false)? When enabled, previews will be +- ADMIN_ENHANCED_PREVIEW: Should the enhanced preview mode be active (true|false)? When enabled, previews will be handled by iFraming in the Client app. This will allow the option of previewing playlists and screens. If disabled, only slides can be previewed. This will be with the "live" method. This preview is not as precise. See [Preview mode in the Client](#preview-mode-in-the-client). @@ -365,31 +369,31 @@ CLIENT_DEBUG=false ###< Client configuration ### ``` -* CLIENT_LOGIN_CHECK_TIMEOUT: How often (milliseconds) should the screen check for status when it is not logged in, and +- CLIENT_LOGIN_CHECK_TIMEOUT: How often (milliseconds) should the screen check for status when it is not logged in, and waiting for being activated in the administration. **Default**: 20 s. -* CLIENT_REFRESH_TOKEN_TIMEOUT: How often (milliseconds) should it be checked whether the token needs to be refreshed? +- CLIENT_REFRESH_TOKEN_TIMEOUT: How often (milliseconds) should it be checked whether the token needs to be refreshed? **Default**: 30 s. -* CLIENT_REFRESH_TOKEN_TIMEOUT: How often (milliseconds) should it be checked whether the token needs to be refreshed? +- CLIENT_REFRESH_TOKEN_TIMEOUT: How often (milliseconds) should it be checked whether the token needs to be refreshed? **Default**: 60 s. -* CLIENT_SCHEDULING_INTERVAL: How often (milliseconds) should the scheduling be run for the logged in screen? +- CLIENT_SCHEDULING_INTERVAL: How often (milliseconds) should the scheduling be run for the logged in screen? **Default**: 60 s. -* CLIENT_PULL_STRATEGY_INTERVAL: How often (milliseconds) should data be pulled from the API? +- CLIENT_PULL_STRATEGY_INTERVAL: How often (milliseconds) should data be pulled from the API? **Default**: 1 m. and 30 s. -* CLIENT_COLOR_SCHEME: Which colour scheme should be enabled? Should be a json object as string. +- CLIENT_COLOR_SCHEME: Which colour scheme should be enabled? Should be a json object as string. This is used to signal how changes to darkmode are handled. Options are: - * Not set - will use the browsers prefers-color-scheme setting. - * '{"type":"library","lat":56.0,"lng":10.0}' - In this case the change to darkmode is handled with a library that + - Not set - will use the browsers prefers-color-scheme setting. + - '{"type":"library","lat":56.0,"lng":10.0}' - In this case the change to darkmode is handled with a library that activates darkmode according to sunrise/sunset of the location given by the longitude/latitude (lat/lng). **Default**: Library mode with a lat/lng set in Denmark. -* CLIENT_DEBUG: Should the Client be in debug mode (true|false). When not in debug mode the mouse pointer is hidden. +- CLIENT_DEBUG: Should the Client be in debug mode (true|false). When not in debug mode the mouse pointer is hidden. **Default**: Disabled. From 807444b40e6414f9fd3391bba1d30c2e9566cb28 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Sat, 30 Aug 2025 09:09:37 +0200 Subject: [PATCH 08/19] 4565: Started work on Upgrade guide --- .env | 3 -- UPGRADE.md | 43 +++++++++++++++++++ UPGRADELOG.md | 11 ----- config/services.yaml | 1 - .../Client/ClientConfigController.php | 2 - 5 files changed, 43 insertions(+), 17 deletions(-) create mode 100644 UPGRADE.md delete mode 100644 UPGRADELOG.md diff --git a/.env b/.env index 93e617a9..65e19975 100644 --- a/.env +++ b/.env @@ -108,7 +108,6 @@ CALENDAR_API_FEED_SOURCE_CACHE_EXPIRE_SECONDS=300 ###< Calendar Api Feed Source ### ###> Admin configuration ### -### Will be injected in the html of the admin page. ADMIN_REJSEPLANEN_APIKEY= ADMIN_SHOW_SCREEN_STATUS=false ADMIN_TOUCH_BUTTON_REGIONS=false @@ -117,7 +116,6 @@ ADMIN_ENHANCED_PREVIEW=false ###< Admin configuration ### ###> Client configuration ### -### Will be injected in the html of the client page. CLIENT_LOGIN_CHECK_TIMEOUT=20000 CLIENT_REFRESH_TOKEN_TIMEOUT=300000 CLIENT_RELEASE_TIMESTAMP_INTERVAL_TIMEOUT=600000 @@ -125,5 +123,4 @@ CLIENT_SCHEDULING_INTERVAL=60000 CLIENT_PULL_STRATEGY_INTERVAL=90000 CLIENT_COLOR_SCHEME='{"type":"library","lat":56.0,"lng":10.0}' CLIENT_DEBUG=false -CLIENT_LOGGING='[]' ###< Client configuration ### diff --git a/UPGRADE.md b/UPGRADE.md new file mode 100644 index 00000000..5a7dcd35 --- /dev/null +++ b/UPGRADE.md @@ -0,0 +1,43 @@ +# Upgrade Guide + +## 2.x -> 3.0.0 + +When upgrading from 2.x to 3.0.0 of OS2Display, a mayor change has been introduced to the project. +The Admin and Client apps that previously existed in separate repositories from the API, have been included in the API +repository. +The API repository has been renamed to https://github.com/os2display/display instead of +https://github.com/os2display/display-api-service since is consists of the complete OS2Display project. +The repositories for Admin and Client will be marked as deprecated. + +Because of these changes, it will be necessary to adjust the server setup to match the new structure. + +TODO: Describe how standard infrastructure is set up after the change. + +### Upgrade steps + +1. Upgrade the API to the latest version of 2.x. +2. Add the following environment variables to `.env.local`: + + ```dotenv + ###> Admin configuration ### + ADMIN_REJSEPLANEN_APIKEY= + ADMIN_SHOW_SCREEN_STATUS=false + ADMIN_TOUCH_BUTTON_REGIONS=false + ADMIN_LOGIN_METHODS='[{"type":"username-password","enabled":true,"provider":"username-password","label":""}]' + ADMIN_ENHANCED_PREVIEW=false + ###< Admin configuration ### + + ###> Client configuration ### + CLIENT_LOGIN_CHECK_TIMEOUT=20000 + CLIENT_REFRESH_TOKEN_TIMEOUT=300000 + CLIENT_RELEASE_TIMESTAMP_INTERVAL_TIMEOUT=600000 + CLIENT_SCHEDULING_INTERVAL=60000 + CLIENT_PULL_STRATEGY_INTERVAL=90000 + CLIENT_COLOR_SCHEME='{"type":"library","lat":56.0,"lng":10.0}' + CLIENT_DEBUG=false + ###< Client configuration ### + ``` + + These values were previously added to Admin and Client: `/public/config.json`. + See [README.md](./README.md) for a description of the configuration options. +3. Run doctrine migrate. diff --git a/UPGRADELOG.md b/UPGRADELOG.md deleted file mode 100644 index 6e3cc768..00000000 --- a/UPGRADELOG.md +++ /dev/null @@ -1,11 +0,0 @@ -# Upgrade log - -## 2.x -> 3.0.0 - -1. Upgrade the API to the latest version of 2.x. -2. Add the following environment variables to `.env.local`: - - These values were previously added to admin|client: `/public/config.json`. - See `README.md` for configuration options. -3. Run doctrine migrate -4. diff --git a/config/services.yaml b/config/services.yaml index 1e6406c7..0b30af9c 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -70,7 +70,6 @@ services: $pullStrategyInterval: '%env(int:CLIENT_PULL_STRATEGY_INTERVAL)%' $colorScheme: '%env(json:CLIENT_COLOR_SCHEME)%' $debug: '%env(bool:CLIENT_DEBUG)%' - $logging: '%env(json:CLIENT_LOGGING)%' App\Feed\EventDatabaseApiV2FeedType: arguments: diff --git a/src/Controller/Client/ClientConfigController.php b/src/Controller/Client/ClientConfigController.php index aa0ffb88..7bf32457 100644 --- a/src/Controller/Client/ClientConfigController.php +++ b/src/Controller/Client/ClientConfigController.php @@ -20,7 +20,6 @@ public function __construct( private readonly int $pullStrategyInterval, private readonly array $colorScheme, private readonly bool $debug, - private readonly array $logging, ) {} public function __invoke(): Response @@ -33,7 +32,6 @@ public function __invoke(): Response 'schedulingInterval' => $this->schedulingInterval, 'colorScheme' => $this->colorScheme, 'debug' => $this->debug, - 'logging' => $this->logging, ]); } } From d6ca934d28f72b7fe3b637505d07448f4e56b636 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Sat, 30 Aug 2025 09:13:26 +0200 Subject: [PATCH 09/19] 4565: Text change --- UPGRADE.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 5a7dcd35..1019b3a4 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -5,8 +5,8 @@ When upgrading from 2.x to 3.0.0 of OS2Display, a mayor change has been introduced to the project. The Admin and Client apps that previously existed in separate repositories from the API, have been included in the API repository. -The API repository has been renamed to https://github.com/os2display/display instead of -https://github.com/os2display/display-api-service since is consists of the complete OS2Display project. +The API repository has been renamed from https://github.com/os2display/display-api-service to +https://github.com/os2display/display since is now consists of the complete OS2Display project. The repositories for Admin and Client will be marked as deprecated. Because of these changes, it will be necessary to adjust the server setup to match the new structure. From c5059566f4cfe8e1694c8d144adde430289f1db9 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Sat, 30 Aug 2025 09:19:53 +0200 Subject: [PATCH 10/19] 4565: Applied coding standards --- UPGRADE.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/UPGRADE.md b/UPGRADE.md index 1019b3a4..ea4e617e 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -5,9 +5,9 @@ When upgrading from 2.x to 3.0.0 of OS2Display, a mayor change has been introduced to the project. The Admin and Client apps that previously existed in separate repositories from the API, have been included in the API repository. -The API repository has been renamed from https://github.com/os2display/display-api-service to -https://github.com/os2display/display since is now consists of the complete OS2Display project. -The repositories for Admin and Client will be marked as deprecated. +The API repository has been renamed from to + since it now contains the complete OS2Display project. +The repositories for admin, client and templates will be marked as archived. Because of these changes, it will be necessary to adjust the server setup to match the new structure. From 97873d75f4f24bdc781749bc9f3543446e4b3344 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Sat, 30 Aug 2025 10:09:34 +0200 Subject: [PATCH 11/19] 4565: Added to documentation. Fixed typo in .env variable --- .env | 13 ++-- README.md | 64 +++++++++++++++++++ UPGRADE.md | 21 +++++- config/services.yaml | 2 +- .../calender-api-feed.md | 0 docs/configuration/openid-connect.md | 29 +++++++++ docs/feed/feed-overview.md | 27 -------- .../etc/confd/templates/env.local.tmpl | 2 +- 8 files changed, 120 insertions(+), 38 deletions(-) rename docs/{feed => configuration}/calender-api-feed.md (100%) create mode 100644 docs/configuration/openid-connect.md delete mode 100644 docs/feed/feed-overview.md diff --git a/.env b/.env index 65e19975..c8ead6f1 100644 --- a/.env +++ b/.env @@ -43,16 +43,16 @@ CORS_ALLOW_ORIGIN='^https?://(localhost|127\.0\.0\.1)(:[0-9]+)?$' JWT_SECRET_KEY=%kernel.project_dir%/config/jwt/private.pem JWT_PUBLIC_KEY=%kernel.project_dir%/config/jwt/public.pem JWT_PASSPHRASE=APP_JWT_PASSPHRASE -# 1 hour +# Default: 1 hour JWT_TOKEN_TTL=3600 -# 15 days +# Default: 15 days JWT_SCREEN_TOKEN_TTL=1296000 ###< lexik/jwt-authentication-bundle ### ###> gesdinet/jwt-refresh-token-bundle ### -# 2 hours +# Default: 2 hours JWT_REFRESH_TOKEN_TTL=7200 -# 30 days +# Default: 30 days JWT_SCREEN_REFRESH_TOKEN_TTL=2592000 ###< gesdinet/jwt-refresh-token-bundle ### @@ -63,7 +63,7 @@ REDIS_CACHE_DSN=redis://redis:6379/0 ###> App ### APP_DEFAULT_DATE_FORMAT='Y-m-d\TH:i:s.v\Z' -APP_ACTIVATION_CODE_EXPIRE_INTERNAL=P2D +APP_ACTIVATION_CODE_EXPIRE_INTERVAL=P2D APP_KEY_VAULT_SOURCE=ENVIRONMENT APP_KEY_VAULT_JSON="{}" EVENTDATABASE_API_V2_CACHE_EXPIRE_SECONDS=300 @@ -72,6 +72,7 @@ TRACK_SCREEN_INFO_UPDATE_INTERVAL_SECONDS=300 ###< App ### ###> itk-dev/openid-connect-bundle ### +# See docs/feed/openid-connect.md for variable explanations. # internal provider INTERNAL_OIDC_METADATA_URL=INTERNAL_OIDC_METADATA_URL INTERNAL_OIDC_CLIENT_ID=INTERNAL_OIDC_CLIENT_ID @@ -96,7 +97,7 @@ OIDC_CLI_REDIRECT=APP_CLI_REDIRECT_URI ###< itk-dev/openid-connect-bundle ### ###> Calendar Api Feed Source ### -# See docs/feed/calendar-api-feed.md for variable explainations. +# See docs/feed/calendar-api-feed.md for variable explanations. CALENDAR_API_FEED_SOURCE_LOCATION_ENDPOINT= CALENDAR_API_FEED_SOURCE_RESOURCE_ENDPOINT= CALENDAR_API_FEED_SOURCE_EVENT_ENDPOINT= diff --git a/README.md b/README.md index 45170c31..0c72305b 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ 16. [Error codes in the Client](#error-codes-in-the-client) 17. [Preview mode in the Client](#preview-mode-in-the-client) 18. [Custom Templates](#custom-templates) +19. [Upgrade Guide](#upgrade-guide) ## Description @@ -130,6 +131,8 @@ The external provider only handles authentication. A user logging in through the external provider will not be granted access automatically, but will be challenged to enter an activation (invite) code to verify access. +See `docs/feed/openid-connect.md` for environment variables for OpenID Connect configuration. + ### Internal The internal oidc provider gets that user's name, email and tenants from claims. @@ -291,6 +294,29 @@ for information about the code generation. Configuration of the project should be added to `.env.local`. Default values are set in `.env`. +```dotenv +###> App ### +APP_ACTIVATION_CODE_EXPIRE_INTERVAL=P2D +APP_KEY_VAULT_SOURCE=ENVIRONMENT +APP_KEY_VAULT_JSON="{}" +EVENTDATABASE_API_V2_CACHE_EXPIRE_SECONDS=300 +TRACK_SCREEN_INFO=false +TRACK_SCREEN_INFO_UPDATE_INTERVAL_SECONDS=300 +###< App ### +``` + +- APP_ACTIVATION_CODE_EXPIRE_INTERVAL: Specifies how long an external user activation code should live. + The format of the interval should follow . + + **Default**: 2 days. +- APP_KEY_VAULT_SOURCE: Source of key-value pair for `src/Service/KeyVaultService`. Atm. "ENVIRONMENT" is the only + option. +- APP_KEY_VAULT_JSON: A json object formatted as a string. Contains key-value pairs that can be accessed by through + `src/Service/KeyVaultService`. +- EVENTDATABASE_API_V2_CACHE_EXPIRE_SECONDS: What should the expire be for cache entries in EventDatabaseApiV2FeedType? +- TRACK_SCREEN_INFO: Should screen info be tracked (true|false)? +- TRACK_SCREEN_INFO_UPDATE_INTERVAL_SECONDS: How often (seconds) should the screen info be tracked from API requests? + ### Admin configuration Will be exposed through the `/config/admin` route. @@ -397,6 +423,11 @@ CLIENT_DEBUG=false **Default**: Disabled. +### Other configuration options + +* See `docs/configuration/openid-connect.md` for configuration of OpenID Connect. +* See `docs/configuration/calendar-api-feed.md` for configuration of CalenderApiFeedType. + ## Rest API & Relationships To avoid embedding all relations in REST representations but still allow the clients to minimize the amount of API calls @@ -490,6 +521,35 @@ The preview will use the token and tenant for accessing the data from the api. This feature is used in the Admin for displaying previews of slides, playlists and screens. +## Feeds + +"Feeds" in OS2display are external data sources that can provide up-to-data to slides. The idea is that if you can set +up slide based on a feed and publish it. The Screen Client will then fetch new data from the feed whenever the Slide is +shown on screen. + +The simplest example is a classic RSS news feed. You can set up a slide based on the RSS slide template, configure the +RSS source URL, and whenever the slide is on screen it will show the latest entries from the RSS feed. + +This means that administrators can set up slides and playlists that stays up to date automatically. + +### Architecture + +The "Feed" architecture is designed to enable both generic and custom feed types. To enable this all feed based screen +templates are designed to support a given "feed output model". These are normalized data sets from a given feed type. + +Each feed implementation defines which output model it supports. Thereby multiple feed implementations can support the +same output model. This is done to enable decoupling of the screen templates from the feed implementation. + +For example: + +* If you have a news source that is not a RSS feed you can implement a "FeedSource" that fetches data from your source + then normalizes the data and outputs it as the RSS output model. When setting up RSS slides this feed source can then + be selected as the source for the slide. +* OS2display has calendar templates that can show bookings or meetings. To show data from your specific calendar or + booking system you can implement a "FeedSource" that fetches booking data from your source and normalizes it to match + the calendar output model. + + ## Custom Templates It is possible to include your own templates in your installation. @@ -555,3 +615,7 @@ task psalm:update-baseline ``` Psalm [error level](https://psalm.dev/docs/running_psalm/error_levels/) is set to level 2. + +## Upgrade Guide + +See [UPGRADE.md](UPGRADE.md) for upgrade guides. diff --git a/UPGRADE.md b/UPGRADE.md index ea4e617e..48ea34b9 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -3,13 +3,14 @@ ## 2.x -> 3.0.0 When upgrading from 2.x to 3.0.0 of OS2Display, a mayor change has been introduced to the project. -The Admin and Client apps that previously existed in separate repositories from the API, have been included in the API -repository. +The Admin and Client apps and the Templates that previously existed in separate repositories from the API, +have been included in the API repository. The API repository has been renamed from to since it now contains the complete OS2Display project. -The repositories for admin, client and templates will be marked as archived. +The repositories for admin, client and templates will be archived. Because of these changes, it will be necessary to adjust the server setup to match the new structure. +Specifically TODO: Describe how standard infrastructure is set up after the change. @@ -41,3 +42,17 @@ TODO: Describe how standard infrastructure is set up after the change. These values were previously added to Admin and Client: `/public/config.json`. See [README.md](./README.md) for a description of the configuration options. 3. Run doctrine migrate. +4. Run template list command to see status for installed templates + + ```shell + docker compose exec phpfpm bin/console app:templates:list + ``` + +5. Run template install for enabling templates: + +```shell + docker compose exec phpfpm bin/console app:templates:install + ``` + + - Use `--all` option for installing all available templates. + - Use `--update` option for updating existing templates. diff --git a/config/services.yaml b/config/services.yaml index 0b30af9c..fc1f0b31 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -94,7 +94,7 @@ services: App\Service\UserService: arguments: $hashSalt: '%env(EXTERNAL_OIDC_HASH_SALT)%' - $codeExpireInterval: '%env(string:APP_ACTIVATION_CODE_EXPIRE_INTERNAL)%' + $codeExpireInterval: '%env(string:APP_ACTIVATION_CODE_EXPIRE_INTERVAL)%' App\Security\EventSubscriber\JwtTokenRefreshedSubscriber: arguments: diff --git a/docs/feed/calender-api-feed.md b/docs/configuration/calender-api-feed.md similarity index 100% rename from docs/feed/calender-api-feed.md rename to docs/configuration/calender-api-feed.md diff --git a/docs/configuration/openid-connect.md b/docs/configuration/openid-connect.md new file mode 100644 index 00000000..edadb6d6 --- /dev/null +++ b/docs/configuration/openid-connect.md @@ -0,0 +1,29 @@ +# OpenID Connect environment variables + +```dotenv +###> itk-dev/openid-connect-bundle ### +# internal provider +INTERNAL_OIDC_METADATA_URL=INTERNAL_OIDC_METADATA_URL +INTERNAL_OIDC_CLIENT_ID=INTERNAL_OIDC_CLIENT_ID +INTERNAL_OIDC_CLIENT_SECRET=INTERNAL_OIDC_CLIENT_SECRET +INTERNAL_OIDC_REDIRECT_URI=INTERNAL_OIDC_REDIRECT_URI +INTERNAL_OIDC_LEEWAY=30 +INTERNAL_OIDC_CLAIM_NAME=navn +INTERNAL_OIDC_CLAIM_EMAIL=email +INTERNAL_OIDC_CLAIM_GROUPS=groups + +# external provider +EXTERNAL_OIDC_METADATA_URL=EXTERNAL_OIDC_METADATA_URL +EXTERNAL_OIDC_CLIENT_ID=EXTERNAL_OIDC_CLIENT_ID +EXTERNAL_OIDC_CLIENT_SECRET=EXTERNAL_OIDC_CLIENT_SECRET +EXTERNAL_OIDC_REDIRECT_URI=EXTERNAL_OIDC_REDIRECT_URI +EXTERNAL_OIDC_LEEWAY=30 +EXTERNAL_OIDC_HASH_SALT= +EXTERNAL_OIDC_CLAIM_ID=signinname + +# cli redirect url +OIDC_CLI_REDIRECT=APP_CLI_REDIRECT_URI +###< itk-dev/openid-connect-bundle ### +``` + +TODO: Explain variables. diff --git a/docs/feed/feed-overview.md b/docs/feed/feed-overview.md deleted file mode 100644 index adb2c0af..00000000 --- a/docs/feed/feed-overview.md +++ /dev/null @@ -1,27 +0,0 @@ -# Feed Overview - -"Feeds" in OS2display are external data sources that can provide up-to-data to slides. The idea is that if you can set -up slide based on a feed and publish it. The Screen Client will then fetch new data from the feed whenever the Slide is -shown on screen. - -The simplest example is a classic RSS news feed. You can set up a slide based on the RSS slide template, configure the -RSS source URL, and whenever the slide is on screen it will show the latest entries from the RSS feed. - -This means that administrators can set up slides and playlists that stays up to date automatically. - -## Architecture - -The "Feed" architecture is designed to enable both generic and custom feed types. To enable this all feed based screen -templates are designed to support a given "feed output model". These are normalized data sets from a given feed type. - -Each feed implementation defines which output model it supports. Thereby multiple feed implementations can support the -same output model. This is done to enable decoupling of the screen templates from the feed implementation. - -For example: - -* If you have a news source that is not a RSS feed you can implement a "FeedSource" that fetches data from your source - then normalizes the data and outputs it as the RSS output model. When setting up RSS slides this feed source can then - be selected as the source for the slide. -* OS2display has calendar templates that can show bookings or meetings. To show data from your specific calendar or - booking system you can implement a "FeedSource" that fetches booking data from your source and normalizes it to match - the calendar output model. diff --git a/infrastructure/itkdev/display-api-service/etc/confd/templates/env.local.tmpl b/infrastructure/itkdev/display-api-service/etc/confd/templates/env.local.tmpl index 4491a4df..76e585b9 100644 --- a/infrastructure/itkdev/display-api-service/etc/confd/templates/env.local.tmpl +++ b/infrastructure/itkdev/display-api-service/etc/confd/templates/env.local.tmpl @@ -14,7 +14,7 @@ CORS_ALLOW_ORIGIN={{ getenv "APP_CORS_ALLOW_ORIGIN" "'^https?://localhost(:[0-9] ###> App ### APP_DEFAULT_DATE_FORMAT='{{ getenv "APP_DEFAULT_DATE_FORMAT" "Y-m-d\\TH:i:s\\Z" }}' -APP_ACTIVATION_CODE_EXPIRE_INTERNAL='{{ getenv "APP_ACTIVATION_CODE_EXPIRE_INTERNAL" "P2D" }}' +APP_ACTIVATION_CODE_EXPIRE_INTERVAL='{{ getenv "APP_ACTIVATION_CODE_EXPIRE_INTERVAL" "P2D" }}' ###< App ### ###> lexik/jwt-authentication-bundle ### From 1acfb06d51a79ecb9a74ee3b946f7903f8130e7f Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Sat, 30 Aug 2025 10:18:04 +0200 Subject: [PATCH 12/19] 4565: Changed upgrade guide formatting --- README.md | 9 +++--- UPGRADE.md | 81 +++++++++++++++++++++++++++++------------------------- 2 files changed, 48 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index 0c72305b..0ca8d17d 100644 --- a/README.md +++ b/README.md @@ -425,8 +425,8 @@ CLIENT_DEBUG=false ### Other configuration options -* See `docs/configuration/openid-connect.md` for configuration of OpenID Connect. -* See `docs/configuration/calendar-api-feed.md` for configuration of CalenderApiFeedType. +- See `docs/configuration/openid-connect.md` for configuration of OpenID Connect. +- See `docs/configuration/calendar-api-feed.md` for configuration of CalenderApiFeedType. ## Rest API & Relationships @@ -542,14 +542,13 @@ same output model. This is done to enable decoupling of the screen templates fro For example: -* If you have a news source that is not a RSS feed you can implement a "FeedSource" that fetches data from your source +- If you have a news source that is not a RSS feed you can implement a "FeedSource" that fetches data from your source then normalizes the data and outputs it as the RSS output model. When setting up RSS slides this feed source can then be selected as the source for the slide. -* OS2display has calendar templates that can show bookings or meetings. To show data from your specific calendar or +- OS2display has calendar templates that can show bookings or meetings. To show data from your specific calendar or booking system you can implement a "FeedSource" that fetches booking data from your source and normalizes it to match the calendar output model. - ## Custom Templates It is possible to include your own templates in your installation. diff --git a/UPGRADE.md b/UPGRADE.md index 48ea34b9..b68ad1fd 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -16,43 +16,50 @@ TODO: Describe how standard infrastructure is set up after the change. ### Upgrade steps -1. Upgrade the API to the latest version of 2.x. -2. Add the following environment variables to `.env.local`: - - ```dotenv - ###> Admin configuration ### - ADMIN_REJSEPLANEN_APIKEY= - ADMIN_SHOW_SCREEN_STATUS=false - ADMIN_TOUCH_BUTTON_REGIONS=false - ADMIN_LOGIN_METHODS='[{"type":"username-password","enabled":true,"provider":"username-password","label":""}]' - ADMIN_ENHANCED_PREVIEW=false - ###< Admin configuration ### - - ###> Client configuration ### - CLIENT_LOGIN_CHECK_TIMEOUT=20000 - CLIENT_REFRESH_TOKEN_TIMEOUT=300000 - CLIENT_RELEASE_TIMESTAMP_INTERVAL_TIMEOUT=600000 - CLIENT_SCHEDULING_INTERVAL=60000 - CLIENT_PULL_STRATEGY_INTERVAL=90000 - CLIENT_COLOR_SCHEME='{"type":"library","lat":56.0,"lng":10.0}' - CLIENT_DEBUG=false - ###< Client configuration ### - ``` - - These values were previously added to Admin and Client: `/public/config.json`. - See [README.md](./README.md) for a description of the configuration options. -3. Run doctrine migrate. -4. Run template list command to see status for installed templates - - ```shell - docker compose exec phpfpm bin/console app:templates:list - ``` - -5. Run template install for enabling templates: +#### 1 - Upgrade the API to the latest version of 2.x + +#### 2 - Configure the following environment variables in `.env.local` + +```dotenv +###> Admin configuration ### +ADMIN_REJSEPLANEN_APIKEY= +ADMIN_SHOW_SCREEN_STATUS=false +ADMIN_TOUCH_BUTTON_REGIONS=false +ADMIN_LOGIN_METHODS='[{"type":"username-password","enabled":true,"provider":"username-password","label":""}]' +ADMIN_ENHANCED_PREVIEW=false +###< Admin configuration ### + +###> Client configuration ### +CLIENT_LOGIN_CHECK_TIMEOUT=20000 +CLIENT_REFRESH_TOKEN_TIMEOUT=300000 +CLIENT_RELEASE_TIMESTAMP_INTERVAL_TIMEOUT=600000 +CLIENT_SCHEDULING_INTERVAL=60000 +CLIENT_PULL_STRATEGY_INTERVAL=90000 +CLIENT_COLOR_SCHEME='{"type":"library","lat":56.0,"lng":10.0}' +CLIENT_DEBUG=false +###< Client configuration ### +``` + +These values were previously added to Admin and Client: `/public/config.json`. +See [README.md](./README.md) for a description of the configuration options. + +#### 3 - Run doctrine migrate + +```shell +docker compose exec phpfpm bin/console doctrine:migrations:migrate +``` + +#### 4 - Run template list command to see status for installed templates + +```shell +docker compose exec phpfpm bin/console app:templates:list +``` + +#### 5 - Run template install for enabling templates ```shell - docker compose exec phpfpm bin/console app:templates:install - ``` +docker compose exec phpfpm bin/console app:templates:install +``` - - Use `--all` option for installing all available templates. - - Use `--update` option for updating existing templates. +- Use `--all` option for installing all available templates. +- Use `--update` option for updating existing templates. From 2e43f774f15a0bc2404207909d25fcda4063b90f Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Sat, 30 Aug 2025 10:50:43 +0200 Subject: [PATCH 13/19] 4565: From fixtures from site:install task --- README.md | 19 +++++++++++++++---- Taskfile.yml | 1 - 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0ca8d17d..005a8624 100644 --- a/README.md +++ b/README.md @@ -19,8 +19,9 @@ 15. [Rest API & Relationships](#rest-api--relationships) 16. [Error codes in the Client](#error-codes-in-the-client) 17. [Preview mode in the Client](#preview-mode-in-the-client) -18. [Custom Templates](#custom-templates) -19. [Upgrade Guide](#upgrade-guide) +18. [Feeds](#feeds) +19. [Custom Templates](#custom-templates) +20. [Upgrade Guide](#upgrade-guide) ## Description @@ -69,14 +70,24 @@ task --list-all ## Development setup -Before first setup a JWT Auth keypair should be generated. See [JWT Auth](#jwt-auth). +Before first installation a JWT Auth keypair should be generated. See [JWT Auth](#jwt-auth). + +```shell +docker compose exec phpfpm bin/console lexik:jwt:generate-keypair +``` To get started with the development setup, run the following task command: -```bash +```shell task site-install ``` +If you want to load fixtures, use the command (use the option `--yes` for auto-confirming). + +```shell +task fixtures:load --yes +``` + The fixtures have an admin user: with the password: "apassword". The fixtures have an editor user: with the password: "apassword". diff --git a/Taskfile.yml b/Taskfile.yml index 4bc078f5..6886fb5b 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -30,7 +30,6 @@ tasks: - task compose-up - task composer-install - task db:migrate --yes - - task fixtures:load --yes - task site-open silent: true From 4918285e5b0b035df680689c01933e59c7d6b4e2 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Sat, 30 Aug 2025 10:58:59 +0200 Subject: [PATCH 14/19] 4565: Documentation --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 005a8624..0097bf27 100644 --- a/README.md +++ b/README.md @@ -201,7 +201,7 @@ Either on the command line or through the OpenApi docs at `/docs` You can use the token either by clicking "Authorize" in the docs and entering -```curl +```text Bearer ``` @@ -218,7 +218,7 @@ curl --location --request 'GET' \ ### API tests - PHPUnit -Run automated tests for the API: +We use PHPUnit for API tests: ```shell task test:api From 2e29885fb16fd9d30db0fede812ed42fbc99c473 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Sat, 30 Aug 2025 11:03:17 +0200 Subject: [PATCH 15/19] 4565: Renamed v2 changelog folder --- CHANGELOG.md | 14 ++++++++------ docs/{changelogs => v2-changelogs}/admin.md | 0 docs/{changelogs => v2-changelogs}/api.md | 0 docs/{changelogs => v2-changelogs}/client.md | 0 docs/{changelogs => v2-changelogs}/template.md | 0 5 files changed, 8 insertions(+), 6 deletions(-) rename docs/{changelogs => v2-changelogs}/admin.md (100%) rename docs/{changelogs => v2-changelogs}/api.md (100%) rename docs/{changelogs => v2-changelogs}/client.md (100%) rename docs/{changelogs => v2-changelogs}/template.md (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 62bfeccd..a0018761 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,13 +14,15 @@ All notable changes to this project will be documented in this file. * Removed propTypes. * Upgraded redux-toolkit and how api slices are generated. * Fixed redux-toolkit cache handling. -* Add Taskfile +* Added Taskfile +* Updated developer documentation. ### NB! Prior to 3.x the project was split into separate repositories -Therefore, changelogs were maintained for each repo. These are available here: +Therefore, changelogs were maintained for each repo. The v2 changelogs have been moved to the `docs/v2-changelogs/` +folder. -* API: [docs/changelogs/api.md](docs/changelogs/api.md) -* Admin: [docs/changelogs/admin.md](docs/changelogs/admin.md) -* Template: [docs/changelogs/template.md](docs/changelogs/template.md) -* Client: [docs/changelogs/client.md](docs/changelogs/client.md) +* API: [docs/v2-changelogs/api.md](docs/v2-changelogs/api.md) +* Admin: [docs/v2-changelogs/admin.md](docs/v2-changelogs/admin.md) +* Template: [docs/v2-changelogs/template.md](docs/v2-changelogs/template.md) +* Client: [docs/v2-changelogs/client.md](docs/v2-changelogs/client.md) diff --git a/docs/changelogs/admin.md b/docs/v2-changelogs/admin.md similarity index 100% rename from docs/changelogs/admin.md rename to docs/v2-changelogs/admin.md diff --git a/docs/changelogs/api.md b/docs/v2-changelogs/api.md similarity index 100% rename from docs/changelogs/api.md rename to docs/v2-changelogs/api.md diff --git a/docs/changelogs/client.md b/docs/v2-changelogs/client.md similarity index 100% rename from docs/changelogs/client.md rename to docs/v2-changelogs/client.md diff --git a/docs/changelogs/template.md b/docs/v2-changelogs/template.md similarity index 100% rename from docs/changelogs/template.md rename to docs/v2-changelogs/template.md From 191d527003cc256066b9c70f78695f44b44f1f19 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Mon, 1 Sep 2025 12:09:24 +0200 Subject: [PATCH 16/19] 4565: Fixed issues raised in review --- README.md | 2 +- UPGRADE.md | 5 +---- assets/admin/components/user/login.jsx | 5 +++-- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 0097bf27..6bfe91c6 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ APP_ENV=prod APP_SECRET= ``` -TODO: Add further production instructions: Build steps, release.json, +TODO: Add further production instructions: Build steps, release.json, etc. ## Coding standards diff --git a/UPGRADE.md b/UPGRADE.md index b68ad1fd..4e2334f0 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -2,7 +2,7 @@ ## 2.x -> 3.0.0 -When upgrading from 2.x to 3.0.0 of OS2Display, a mayor change has been introduced to the project. +The upgrade from 2.x to 3.0.0 of OS2Display introduces a major change to the project. The Admin and Client apps and the Templates that previously existed in separate repositories from the API, have been included in the API repository. The API repository has been renamed from to @@ -10,9 +10,6 @@ The API repository has been renamed from loginMethod.type === "oidc", + ({ type }) => type === "oidc", ); + const usernamePasswordLogins = loginMethods.filter( - (loginMethod) => loginMethod.type === "username-password", + ({ type }) => type === "username-password", ); return ( From b27655a5bb120972aea8bbfc263e216a0b6cd75a Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Mon, 1 Sep 2025 12:14:03 +0200 Subject: [PATCH 17/19] 4565: Applied coding standards --- assets/admin/components/user/login.jsx | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/assets/admin/components/user/login.jsx b/assets/admin/components/user/login.jsx index 7bc9afcd..c9f1eabc 100644 --- a/assets/admin/components/user/login.jsx +++ b/assets/admin/components/user/login.jsx @@ -264,9 +264,7 @@ function Login() { }; }, [search]); - const oidcLogins = loginMethods.filter( - ({ type }) => type === "oidc", - ); + const oidcLogins = loginMethods.filter(({ type }) => type === "oidc"); const usernamePasswordLogins = loginMethods.filter( ({ type }) => type === "username-password", From 9913053aba80e24f641236fd44078e39803f9799 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Mon, 1 Sep 2025 12:29:55 +0200 Subject: [PATCH 18/19] 4565: Added task for site install with fixtures --- Taskfile.yml | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/Taskfile.yml b/Taskfile.yml index 6886fb5b..bdb7e896 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -22,7 +22,7 @@ tasks: site-install: prompt: "This will reset your setup. Continue?" - desc: "Install new os2display" + desc: "Install new OS2Display." cmds: - task compose -- down - task compose -- pull @@ -33,6 +33,20 @@ tasks: - task site-open silent: true + site-install-with-fixtures: + prompt: "This will reset your setup. Continue?" + desc: "Install new OS2Display with fixtures installed." + cmds: + - task compose -- down + - task compose -- pull + - task npm-install + - task compose-up + - task composer-install + - task db:migrate --yes + - task fixtures:load --yes + - task site-open + silent: true + site-open: desc: "Opens admin, docs and client." cmds: @@ -86,7 +100,7 @@ tasks: silent: true coding-standards:check: - desc: "Check coding standards" + desc: "Check coding standards." cmds: - task coding-standards:assets:check - task coding-standards:php:check @@ -94,7 +108,7 @@ tasks: - task coding-standards:yml:check coding-standards:apply: - desc: "Apply coding standards" + desc: "Apply coding standards." cmds: - task coding-standards:assets:apply - task coding-standards:php:apply @@ -125,23 +139,23 @@ tasks: - docker compose run --rm --volume "$PWD:/md" prettier 'assets/**/*.{js,jsx}' --check coding-standards:markdown:apply: - desc: "Apply coding standards for Markdown" + desc: "Apply coding standards for Markdown." cmds: - docker compose run --rm --volume "$PWD:/md" markdownlint markdownlint --ignore '**/node_modules/**' --ignore '**/vendor/**' '*.md' 'documentation/*.md' --fix coding-standards:markdown:check: - desc: "Check coding standards for Markdown" + desc: "Check coding standards for Markdown." cmds: - docker compose run --rm --volume "$PWD:/md" markdownlint markdownlint --ignore '**/node_modules/**' --ignore '**/vendor/**' '*.md' 'documentation/*.md' coding-standards:php:apply: - desc: "Apply coding standards for PHP" + desc: "Apply coding standards for PHP." cmds: - task compose -- exec phpfpm vendor/bin/php-cs-fixer fix --diff silent: true coding-standards:php:check: - desc: "Check coding standards for PHP" + desc: "Check coding standards for PHP." cmds: - task compose -- exec phpfpm vendor/bin/php-cs-fixer fix --dry-run --diff silent: true @@ -152,7 +166,7 @@ tasks: - task composer -- code-analysis psalm:update-baseline: - desc: "Updates the Psalm baseline file" + desc: "Updates the Psalm baseline file." cmds: - task compose -- exec phpfpm vendor/bin/psalm --update-baseline @@ -173,32 +187,32 @@ tasks: silent: true test:api: - desc: "Runs API tests (PHPUnit)" + desc: "Runs API tests (PHPUnit)." cmds: - task composer -- test-setup - task compose -- exec --env SYMFONY_DEPRECATIONS_HELPER=disabled phpfpm composer test test:frontend-built: - desc: "Runs frontend tests (Playwright) on the built files. This temporarily stops the node container" + desc: "Runs frontend tests (Playwright) on the built files. This temporarily stops the node container." cmds: - ./scripts/test test:frontend-local: - desc: "Runs frontend tests from the local machine" + desc: "Runs frontend tests from the local machine." cmds: - BASE_URL="https://display.local.itkdev.dk" npx playwright test test:frontend-local-ui: - desc: "Runs frontend tests from the local machine in UI mode" + desc: "Runs frontend tests from the local machine in UI mode." cmds: - BASE_URL="https://display.local.itkdev.dk" npx playwright test --ui generate:api-spec: - desc: "Generate the OpenAPI specifications (in public/) from the API Platform config" + desc: "Generate the OpenAPI specifications (in public/) from the API Platform config." cmds: - task compose -- exec phpfpm composer update-api-spec generate:redux-toolkit-api: - desc: "Generate the RTK Query api slices (in assets/shared/redux/)" + desc: "Generate the RTK Query api slices (in assets/shared/redux/)." cmds: - task compose -- exec node npx @rtk-query/codegen-openapi /app/assets/shared/redux/openapi-config.js From 6f37c6613cd4c5fdb08427fbcbaaab8e2d5deaf9 Mon Sep 17 00:00:00 2001 From: Troels Ugilt Jensen <6103205+tuj@users.noreply.github.com> Date: Mon, 1 Sep 2025 15:14:56 +0200 Subject: [PATCH 19/19] 4565: Removed CORS info from README --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 6bfe91c6..6c3a90a0 100644 --- a/README.md +++ b/README.md @@ -126,8 +126,7 @@ task coding-standards:apply ## Stateless -The API is stateless except `/v2/authentication` routes. -Make sure to set the `CORS_ALLOW_ORIGIN` correctly in `.env.local`. +The API is stateless except for the `/v2/authentication` routes. ## OIDC providers