{"id":13929266,"url":"https://github.com/clearflask/clearflask","last_synced_at":"2026-01-11T13:49:25.088Z","repository":{"id":38791981,"uuid":"392216038","full_name":"clearflask/clearflask","owner":"clearflask","description":"Listen to your users during product development with ClearFlask","archived":false,"fork":false,"pushed_at":"2024-09-12T15:20:09.000Z","size":48436,"stargazers_count":288,"open_issues_count":3,"forks_count":26,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-09-13T03:56:55.946Z","etag":null,"topics":["feedback","roadmap"],"latest_commit_sha":null,"homepage":"https://clearflask.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/clearflask.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-08-03T06:35:20.000Z","updated_at":"2024-09-12T15:21:27.000Z","dependencies_parsed_at":"2023-02-18T19:46:13.255Z","dependency_job_id":"4da1ce4a-a056-4c5b-9a70-560c6c1381df","html_url":"https://github.com/clearflask/clearflask","commit_stats":null,"previous_names":[],"tags_count":57,"template":false,"template_full_name":null,"purl":"pkg:github/clearflask/clearflask","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clearflask%2Fclearflask","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clearflask%2Fclearflask/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clearflask%2Fclearflask/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clearflask%2Fclearflask/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/clearflask","download_url":"https://codeload.github.com/clearflask/clearflask/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/clearflask%2Fclearflask/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265926932,"owners_count":23850886,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["feedback","roadmap"],"created_at":"2024-08-07T18:02:13.440Z","updated_at":"2026-01-11T13:49:25.013Z","avatar_url":"https://github.com/clearflask.png","language":"TypeScript","readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://clearflask.com/\" rel=\"noopener\" target=\"_blank\"\u003e\n    \u003cimg width=\"100\" src=\"./clearflask-frontend/public/img/clearflask-logo.png\" alt=\"Logo\"\u003e\n    \u003cbr /\u003e\n    \u003cpicture\u003e\n      \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"./clearflask-frontend/public/img/clearflask-text-dark.png\"\u003e\n      \u003cimg width=\"300\" src=\"./clearflask-frontend/public/img/clearflask-text.png\" alt=\"ClearFlask\"\u003e\n    \u003c/picture\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://github.com/clearflask/clearflask/actions?query=workflow%3A%22CI%22\"\u003e\n    \u003cimg alt=\"Build Status\" src=\"https://img.shields.io/github/actions/workflow/status/clearflask/clearflask/ci.yml?style=for-the-badge\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/clearflask/clearflask/releases\"\u003e\n    \u003cimg alt=\"GitHub release\" src=\"https://img.shields.io/github/v/release/clearflask/clearflask?include_prereleases\u0026sort=semver\u0026style=for-the-badge\"\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://github.com/clearflask/clearflask/blob/master/COPYING\"\u003e\n    \u003cimg alt=\"License\" src=\"https://img.shields.io/github/license/clearflask/clearflask?style=for-the-badge\"\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n  Open-source Feedback Management Tool.\n  \u003cbr /\u003e\n  Alternative to \u003ca href=\"https://canny.io\"\u003eCanny\u003c/a\u003e and \u003ca href=\"https://uservoice.com/\"\u003eUserVoice\u003c/a\u003e.\n\u003c/div\u003e\n\n\u003cbr /\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003ca href=\"https://www.youtube.com/watch?v=oOw4pxyK6vs\" rel=\"noopener\" target=\"_blank\"\u003e\n    \u003cimg width=\"1024\" src=\"./clearflask-resources/clearflask-video-link.png\" alt=\"Video link\"\u003e\n  \u003c/a\u003e\n  \u003cbr /\u003e\n  \u003cimg width=\"1024\" src=\"./clearflask-frontend/public/img/landing/demo-page-feedback-classic.png\" alt=\"Demo\"\u003e\n  \u003cbr /\u003e\n  \u003cimg width=\"1024\" src=\"./clearflask-frontend/public/img/landing/demo-dashboard-roadmap.png\" alt=\"Demo\"\u003e\n  \u003cbr /\u003e\n  \u003cimg width=\"1024\" src=\"./clearflask-frontend/public/img/landing/demo-dashboard-feedback.png\" alt=\"Demo\"\u003e\n\u003c/div\u003e\n\n### Contents\n\n- [Managed hosting](#managed-hosting)\n- [Self hosting](#self-hosting)\n    - [Quick start](#quick-start)\n    - [Deploy dependencies](#deploy-dependencies)\n        - [Via Docker](#via-docker)\n        - [Via AWS](#via-aws)\n    - [Deploy ClearFlask](#deploy-clearflask)\n        - [Setup](#setup)\n        - [Run](#run)\n    - [Maintenance](#maintenance)\n        - [Migration between Elasticsearch/MySQL](#migration-between-elasticsearchmysql)\n- [Contributing](#contributing)\n    - [Code quality](#code-quality)\n    - [Building](#building)\n    - [Architecture](#architecture)\n    - [Release](#release)\n- [Security Policy](#security-policy)\n\n# Managed Hosting\n\nSupport our open-source development by choosing cloud hosting with [scalable pricing](https://clearflask.com/pricing),\ncheck us out on [our website](https://clearflask.com).\n\n# Self Hosting\n\n## Quick start\n\nFor a quick start using [Docker](https://www.docker.com/products/docker-desktop), download\nthe [Docker Compose service file](clearflask-release/src/main/docker/compose/docker-compose.self-host.yml)\nas `docker-compose.yml`, and run the following:\n\n```shell\ndocker-compose --profile with-deps up\n```\n\nPoint your browser at [http://localhost](http://localhost) and create an account using email `admin@localhost`.\n\nYou also want to setup outgoing mail, read the [Email section](#email).\n\nIf you wish to host it on your domain other than `localhost`, read the [DNS section](#dns) and then\nsetup [SSL/TLS certificates](#certificate-management).\n\n## Replace dependencies\n\nThere are several dependencies that you can swap out for ClearFlask:\n\n- **AWS DynamoDB** or **Localstack** or API-compatible alternative (ScyllaDB is not fully compatible)\n- **MinIO** or **AWS S3** or API-compatible alternative\n- One of:\n    - **MySQL** or **Aurora**\n    - **ElasticSearch** or **OpenSearch**\n- **Email service via SMTP** or **AWS SES**\n\nAnd a few optional:\n\n- **Google ReCaptcha**\n- **Let's Encrypt** automagic certificate management\n- **CloudFront** as a CDN (Use in front of `clearflask-connect`)\n\n### Via Docker\n\nYou can spin up all dependencies via Docker.\n\nSimply add the `--profile with-deps` to your `docker-compose` command when starting ClearFlask.\n\nAll database content will be persisted to local filesystem under `data` folder.\n\n### Via AWS\n\nFor production workload, you will want to spin up these dependencies yourself and point ClearFlask to their endpoints.\n\n##### IAM access\n\nFor AWS services, `clearflask-server` auto-detects Access Keys using either a configuration property or the default\nlocations. If you are running in EC2 or ECS, keys detection is automated, you just need to create the appropriate IAM\nrole.\n\n##### AWS DynamoDB\n\nProvide IAM access including create table permission as table is created automatically by ClearFlask on startup.\n\nIAM actions:\n\n- CreateTable\n- BatchGetItem\n- GetItem\n- Query\n- BatchWriteItem\n- DeleteItem\n- PutItem\n- UpdateItem\n\n##### AWS S3\n\nCreate a private bucket with IAM access to ClearFlask.\n\nIAM actions:\n\n- ListBucket\n- GetObject\n- DeleteObject\n- PutObject\n\nYou can also use an API-compatible alternative service such as Wasabi, MinIO...\n\n##### ElasticSearch or MySQL\n\nRecommended is AWS ES, give the proper IAM access\n\nIAM actions, all in these categories:\n\n- List\n- Read\n- Write\n- Tagging\n\nAlternatively you can deploy it yourself (cheaper) or host it on Elastic. Or you can choose to use MySQL/Aurora as a\ncheaper alternative.\n\n##### AWS SES\n\nIn order to setup SES, you need to seek limit increase via AWS support.\n\nChange the config property `...EmailServiceImpl$Config.useService` to `ses` and give the proper IAM access.\n\nIAM actions:\n\n- SendEmail\n- SendRawEmail\n\nAlternatively use any other email provider and fill out the SMTP settings\n\n## Deploy ClearFlask\n\nClearFlask consists of two components:\n\n- Tomcat application for serving API requests\n- NodeJS for SSR, dynamic cert management and serving static files\n\n### Setup\n\n1. Download the [Docker Compose service file](clearflask-release/src/main/docker/compose/docker-compose.self-host.yml)\n2. Run it with `docker-compose --profile with-deps up` which creates few configuration files in your local directory\n3. Carefully read and modify `server/config-selfhost.cfg`.\n4. Carefully read and modify `connect/connect.config.json`.\n5. Adjust the Docker Compose service file to add/remove dependencies if you are hosting them outside of Docker\n\n#### Email\n\nBy default, email is configured for AWS SES pointing to your Localstack (which doesn't do anything).\n\nYou can choose to setup your own SMTP server or use AWS SES.\n\n##### Email using SMTP\n\nChange the configuration to SMTP:\n\n- `com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.useService`: `smtp`\n\nThen you need to gather your SMTP settings and fill out the following:\n\n- `com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.smtpStrategy`: `SMTP_TLS`\n  (SMTP_TLS, SMTPS, SMTP)\n- `com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.smtpHost`: `smtp.gmail.com`\n  (e.g. smtp.gmail.com)\n- `com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.smtpPort`: `587`\n  (587 for SMTP_TLS, 465 for SMTPS, 25 for SMTP)\n- `com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.smtpUser`: `my.name@gmail.com`\n  (e.g. my.name@gmail.com)\n- `com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.smtpPassword`: `asdfqwerzxcvasdf`\n  (To get this working, you need to enable IMAP if not enabled. If you use 2FA, you need to generate an app password and\n  use it here)\n- `com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.emailDisplayName`: `ClearFlask`\n  (e.g. 'ClearFlask for MyCompany')\n- `com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.fromEmailLocalPart`: `my.name`\n  (first part of your email, for my.name@gmail.com, it would be 'my.name')\n- `com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.fromEmailDomainOverride`: `gmail.com`\n  (domain part of your email, for my.name@gmail.com, it would be 'gmail.com')\n\n##### Email using AWS SES\n\nChange the configuration to SMTP:\n\n- `com.smotana.clearflask.core.push.provider.EmailServiceImpl$Config.useService`: `ses`\n\nThen fill out the SES settings:\n\n- `com.smotana.clearflask.core.email.AmazonSimpleEmailServiceProvider$Config.region`: `us-east-1`\n- `com.smotana.clearflask.core.email.AmazonSimpleEmailServiceProvider$Config.serviceEndpoint`: (Leave blank, unless you\n  need to override)\n\n#### DNS\n\nBy default, everything is assumed to be on `localhost`. If you wish to host your portal on `yoursite.com`\nor `192.168.1.123`, set the following properties:\n\n- `connect.config.json:parentDomain`: `yoursite.com`\n- `config-selfhost.cfg:com.smotana.clearflask.web.Application$Config.domain`: `yoursite.com`\n\n#### Certificate management\n\n##### Automagic using Let's Encrypt\n\nIf you wish to have certificates fetched and renewed for you automagically using Let's Encrypt, ensure your DNS is\ncorrectly pointing to your server, it is publicly accessible, and set the following config parameters:\n\n- `connect.config.json:disableAutoFetchCertificate`: `false`\n- `connect.config.json:forceRedirectHttpToHttps`: `true`\n- `config-selfhost.cfg:com.smotana.clearflask.web.security.AuthCookieImpl$Config.authCookieSecure`: `true`\n\nOnce you load your site for the first time, a Certificate is auto-magically fetched for you.\n\n##### Static certificate\n\nIf you wish to use your own certificate, set the following properties:\n\n- `connect.config.json:disableAutoFetchCertificate`: `false`\n- `connect.config.json:forceRedirectHttpToHttps`: `true`\n- `config-selfhost.cfg:com.smotana.clearflask.web.security.AuthCookieImpl$Config.authCookieSecure`: `true`\n- `config-selfhost.cfg:com.smotana.clearflask.security.CertFetcherImpl$Config.staticCert`: `\u003cSEE BELOW\u003e`\n\nFor the `staticCert` property value, this has to be a JSON object with the following structure, but you need to put it\nin a single line:\n\n```json\n{\n    \"cert\": {\n        \"cert\": \"-----BEGIN CERTIFICATE-----\\nMIIFFjCC...\",\n        \"chain\": \"-----BEGIN CERTIFICATE-----\\nMIIE/jCC\",\n        \"subject\": \"feedback.example.com\",\n        \"altnames\": [\n            \"feedback.example.com\"\n        ],\n        \"issuedAt\": 1709572939000,\n        \"expiresAt\": 1741108939000\n    },\n    \"keypair\": {\n        \"privateKeyPem\": \"-----BEGIN PRIVATE KEY-----\\nMIIEvwIB...\"\n    }\n}\n```\n\nNote that you have to put this into a single line. The cert, chain and keypair will replace any literal `\\n` into a\nnewline.\n\nThis approach is not recommended as you will have to update this certificate manually.\n\n##### Self-managed behind reverse proxy\n\nClearFlask wasn't designed to be deployed on a subpath (e.g. `example.com/clearflask/`), rather it is\nintended to be deployed either directly on a domain or a subdomain. (e.g. `examplefeedback.com` or\n`feedback.example.com`)\n\nIf you are managing TLS certificates behind a reverse proxy, redirect all `http` requests to `https`, set the following\nconfig:\n\n- `connect.config.json:disableAutoFetchCertificate`: `true`\n- `connect.config.json:forceRedirectHttpToHttps`: `true`\n- `config-selfhost.cfg:com.smotana.clearflask.web.security.AuthCookieImpl$Config.authCookieSecure`: `true`\n\n##### No certificates\n\nAlthough discouraged, you can run ClearFlask over HTTP only. Ensure these settings are set:\n\n- `connect.config.json:disableAutoFetchCertificate`: `true`\n- `connect.config.json:forceRedirectHttpToHttps`: `false`\n- `config-selfhost.cfg:com.smotana.clearflask.web.security.AuthCookieImpl$Config.authCookieSecure`: `false`\n\n#### Dashboard account\n\nFor you to manage the dashboard, you need to whitelist an email to be able to create a super-admin account:\n\n`config-selfhost.cfg:com.smotana.clearflask.web.security.SuperAdminPredicate$Config.superAdminEmailRegex`:\n`^admin@yoursite.com$`\n\nAfter you sign-up, disable further signups using:\n\n`config-selfhost.cfg:com.smotana.clearflask.web.resource.AccountResource$Config.signupEnabled`: `false`\n\n### Run\n\n1. Run `docker-compose up` or `docker-compose --profile with-deps up` to also start dependencies.\n2. Point your browser at `http://localhost` or if you configured your DNS `https://yoursite.com`.\n3. Create an account using `admin@localhost` email or based on your configuration of `superAdminEmailRegex`.\n\n## Maintenance\n\n### Migration between ElasticSearch/MySQL\n\nSource of truth data is stored in a NoSQL DynamoDB compatible database. For searching/filtering, you have a choice of\nusing a separate database:\n\nElasticSearch:\n\n- Intended for large projects\n- Searching is great (example: searching for 'Johnny' will find 'Jonathan')\n\nMySQL:\n\n- Intended for small projects\n- Lightweight\n- Cheap to host\n- Searching is idential match only (example: searching for 'Jon' will find 'Jonathan')\n\n#### Migration prerequisites\n\nTo check what you are using now, open your configuration file `config-selfhost.cfg` for the\nproperty `com.smotana.clearflask.web.Application$Config.defaultSearchEngine`. If you can't find it, the default value\nuses ElasticSearch.\n\nYou will need a JMX client such\nas [jconsole](https://docs.oracle.com/javase/7/docs/technotes/guides/management/jconsole.html) probably already bundled\nwith your JRE/JDK on your system or [VisualVM](https://visualvm.github.io/). To connect to your running instance, you\nneed to enable port forwarding in your `docker-compose.yml` file by uncommenting the `JMX` ports and restarting. Then\nyou can connect to `service:jmx:rmi:///jndi/rmi://localhost:9950/jmxrmi` without credentials and without SSL.\n\nDuring the migration, you should be checking the logs for any warnings or errors. Especially when starting up or\ninvoking a JMX method. If you run in to issues, document it, open an issue on GitHub and optionally rolback by undoing\nall the steps in reverse order.\n\n#### Migrate from Mysql to ElasticSearch\n\n1. Double check you are using MySQL, you should have this property\n   set: `config-selfhost.cfg:com.smotana.clearflask.web.Application$Config.defaultSearchEngine`: `READWRITE_MYSQL`\n2. Edit `docker-compose.yml`:\n    1. Uncomment `clearflask-server` container's JMX ports `9950:9950` and `9951:9951`\n    2. Uncomment `elasticsearch` container\n    3. Restart the server\n3. Using JMX, invoke `com.smotana.clearflask.web.resource.ProjectResource`.`createIndexes`(`true`, `false`); On failure,\n   check the logs\n4. Edit `docker-compose.yml`\n    1. Change `com.smotana.clearflask.web.Application$Config.defaultSearchEngine` to `READ_MYSQL_WRITE_BOTH`\n    2. Restart the server\n5. Using JMX, invoke `com.smotana.clearflask.web.resource.ProjectResource`.`reindexProjects`(`true`, `true`, `false`)\n6. At this point you are using both ElasticSearch and MySQL but reading only from MySQL. To test a single project with\n   ElasticSearch, as super admin open `https://\u003cyour_domain\u003e/dashboard/settings/project/advanced` and at the bottom of\n   the page force override the search engine to ElasticSearch. Remember to unset this property before continuing.\n7. Edit `docker-compose.yml`\n    1. Change `com.smotana.clearflask.web.Application$Config.defaultSearchEngine` to `READ_ELASTICSEARCH_WRITE_BOTH`\n    2. Restart the server and ensure every project is working well.\n8. Edit `docker-compose.yml` and change `com.smotana.clearflask.web.Application$Config.defaultSearchEngine`\n   to `READWRITE_ELASTICSEARCH`\n9. Edit `docker-compose.yml`:\n    1. Comment out `mysql-db` container to prevent it from starting up.\n    2. Comment out `clearflask-server` container's JMX ports `9950:9950` and `9951:9951`\n    3. Restart the server\n10. Remove the leftover data stored by the now non-functional MySQL container.\n\n#### Migrate from ElasticSearch to Mysql\n\n1. Double check you are using ElasticSearch, you may have this property\n   set: `config-selfhost.cfg:com.smotana.clearflask.web.Application$Config.defaultSearchEngine`:\n   `READWRITE_ELASTICSEARCH`\n   . If it is missing, the default is ElasticSearch\n2. Edit `docker-compose.yml`:\n    1. Uncomment `clearflask-server` container's JMX ports `9950:9950` and `9951:9951`\n    2. Uncomment `mysql-db` container\n    3. Restart the server\n3. Using JMX, invoke `com.smotana.clearflask.web.resource.ProjectResource`.`createIndexes`(`false`, `true`); On failure,\n   check the logs\n4. Edit `docker-compose.yml`\n    1. Change `com.smotana.clearflask.web.Application$Config.defaultSearchEngine`\n       to `READ_ELASTICSEARCH_WRITE_BOTH`\n    2. Restart the server\n5. Using JMX, invoke `com.smotana.clearflask.web.resource.ProjectResource`.`reindexProjects`(`true`, `false`, `true`)\n6. At this point you are using both ElasticSearch and MySQL but reading only from ElasticSearch. To test a single\n   project with MySQL, as super admin open `https://\u003cyour_domain\u003e/dashboard/settings/project/advanced` and at the bottom\n   of the page force override the search engine to MySQL. Remember to unset this property before continuing.\n7. Edit `docker-compose.yml`\n    1. Change `com.smotana.clearflask.web.Application$Config.defaultSearchEngine`\n       to `READ_MYSQL_WRITE_BOTH`\n    2. Restart the server and ensure every project is working well.\n8. Edit `docker-compose.yml` and change `com.smotana.clearflask.web.Application$Config.defaultSearchEngine`\n   to `READWRITE_MYSQL`\n9. Edit `docker-compose.yml`:\n    1. Comment out `elasticsearch` container to prevent it from starting up.\n    2. Comment out `clearflask-server` container's JMX ports `9950:9950` and `9951:9951`\n    3. Restart the server\n10. Remove the leftover data stored by the now non-functional ElasticSearch container.\n\n### Telemetry\n\nTo disable any telemetry, set the following configuration property:\n\n`config-selfhost.cfg:com.smotana.clearflask.Application$Config.enableTelemetry`: `false`\n\n# Contributing\n\nYour contributions are very much appreciated. Please see here on how to contribute to our codebase.\n\n## Code quality\n\n### Java\n\n- Generally following the [Google Java Style Guide](https://google.github.io/styleguide/javaguide.html)\n- **IntelliJ** Recommended: Code style formatting is in `.idea` folder\n- It is expected to write a test for each functionality.\n\n### JS/TS\n\n- **VisualCode** recommended: code formatting and properties are defined in `.vscode` folder\n- We are yet to establish a proper test framework. A proposal would be welcome.\n\n## Building\n\n### Environment setup\n\nDevelopment has been done under Mac, Linux, and Windows (with WSL)\n\nThe following requirements are a minimum:\n\n- Java 11\n- Maven\n- Makefile (for local and production deployment)\n- Docker\n- FFmpeg and ffprobe (For `babel-plugin-transform-media-imports`)\n- OpenSSL (For local deployment's self-signed certs)\n\n```shell\nbrew install maven ffmpeg make openssl\n```\n\nPlease let us know if we missed anything.\n\n### Compile and build\n\nBuilding is straightforward and can be done by running:\n\n```shell\nmvn clean install\n```\n\nAdd `-DskipTests` or `-DskipITs` to skip all tests or just Integration tests respectively.\n\nFor developing integration tests, you may want to start a local instance of ClearFlask and run integrations directly\nfrom your IDE. Otherwise you will have to alwasy spin up all dependencies.\n\n### Run locally\n\nThere are several ways to run locally depending on what you want to test.\n\n#### Frontend + Mock backend\n\nIdeal for fast-iteration on frontend changes. Changes to code take effect immediately.\n\n```shell\nmake frontend-start\n```\n\nOpen browser at [http://localhost:3000](http://localhost:3000).\n\n#### Connect + Frontend + Mock backend\n\nIntended for testing Connect and SSR. For code changes to take effect, you must rebuild clearflask-frontend.\n\n```shell\nmake connect-start\n```\n\nOpen browser at [http://localhost:9080](http://localhost:9080).\n\n#### HTTPS + Connect + Frontend + Backend\n\nIntended for testing the whole deal before deployment. For code changes to take effect, you must completely rebuild\nclearflask.\n\n```shell\nmake local-up\nmake local-down\n```\n\nOpen browser at [https://localhost](https://localhost).\n\n#### Connect + Frontend + Backend (Self-host)\n\nIntended for testing self-host deployment, uses locally built Docker images rather than officially released images. For\ncode changes to take effect, you must completely rebuild clearflask.\n\n```shell\nmake selfhost-up\nmake selfhost-down\n```\n\nOpen browser at [https://localhost](https://localhost).\n\n### Debugging\n\nWhen running a local deploy, you can debug various components:\n\n#### Attach debugger\n\nFor debugging `clearflask-server` running on Tomcat, point IntelliJ IDEA or your favourite IDE to remote JVM debug\non `localhost:9999`.\n\n#### JMX\n\nFor changing configuration parameters or running exposed operations, connect via JMX using your favourite tool (\nJVisualVM, JConsole, ...) on `localhost:9950` without credentials and without SSL.\n\n#### ElasticSearch Kibana\n\nTo look at the ES cluster and run commands, point your browser at `http://localhost:5601`.\n\n#### KillBill Kaui\n\nTo look at the billing sysstem, point your browser at `http://localhost:8081`.\n\nCredentials are `admin/password` and API key and secret is `bob/lazar`.\n\nIf you are debugging an Integration Test, a log line will reveal the API key and\nsecret: `KillBill test randomized apiKey {} secretKey {}`.\n\n#### AWS services (DynamoDB, Route53, SES, S3)\n\nYou can use regular AWS command line tool and point it to our mocked up LocalStack services:\n\n```shell\naws --endpoint-url=http://localhost:4566 ...\n```\n\n## Architecture\n\n### Overall view\n\nThe following is a production deployment of ClearFlask. It was once scribbled down during a conversation and now it's an\nofficial architecture diagram until we have a better replacement.\n\n![Architecture diagram](clearflask-resources/clearflask-architecture.png)\n\n### Project Structure\n\n##### clearflask-api\n\nContains OpenAPI definition for communication between frontend and backend. Also includes definition of project\nsettings.\n\n##### clearflask-frontend\n\nClient side React application containing the Landing page, customer dashboard and portal. Entry point is `index.ts`.\n\nAlso contains a NodeJS server nicknamed `Connect` that serves static files, Server-Side Rendered page as well as\nhandling dynamic TLS certificate issuing for customers. Entry point is `connect.ts`.\n\n##### clearflask-legal\n\nResource module containing Privacy Policy and Terms of Service documents.\n\n##### clearflask-logging\n\nServer logging module used for formattinbg logs as well as sending criticial emails to SRE of any warnings or errors. It\nis a separate package since it's used by both `clearflask-server` as well as KillBill servers.\n\n##### clearflask-resources\n\nClearFlask official vector logo and resources.\n\n##### clearflask-server\n\nServer implementation of the OpenAPI definition to serve requests from clients. Uses several dependencies:\n\n- DynamoDB: Most data is stored in this NoSQL database for fast access and scalability\n- ElasticSearch: For relevant results and searching, data is replicated to ES for fast searching.\n- S3: User uploaded images are served directly from S3.\n- KillBill: For payment processing and billing management, KillBill is used.\n\n## Release\n\nIntended for ClearFlask developers, this guide is for making a release of ClearFlask to create Docker images and Maven\nartifacts.\n\n### Prerequisites\n\nYou need credentials for uploading to GitHub Packages repository for both Docker and Maven.\n\nIn GitHub personal settings create a PAT with `read:packages`, `write:packages`, and `delete:packages` scopes.\n\nFor Docker registry, run this command and input your PAT as password:\n\n```shell\ndocker login ghcr.io -u USERNAME\n```\n\nThen fill out the following with your PAT and put it under `~/.m2/settings.xml`:\n\n```xml\n\n\u003csettings xmlns=\"http://maven.apache.org/SETTINGS/1.0.0\"\n          xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n          xsi:schemaLocation=\"http://maven.apache.org/SETTINGS/1.0.0\n                          https://maven.apache.org/xsd/settings-1.0.0.xsd\"\u003e\n\n    \u003cservers\u003e\n        \u003cserver\u003e\n            \u003cid\u003egithub\u003c/id\u003e\n            \u003cusername\u003ematusfaro\u003c/username\u003e\n            \u003cpassword\u003e~~INSERT PAT TOKEN~~\u003c/password\u003e\n        \u003c/server\u003e\n    \u003c/servers\u003e\n\n    \u003cprofiles\u003e\n        \u003cprofile\u003e\n            \u003cid\u003egithub\u003c/id\u003e\n            \u003crepositories\u003e\n                \u003crepository\u003e\n                    \u003cid\u003ecentral\u003c/id\u003e\n                    \u003curl\u003ehttps://repo1.maven.org/maven2\u003c/url\u003e\n                \u003c/repository\u003e\n                \u003crepository\u003e\n                    \u003cid\u003egithub\u003c/id\u003e\n                    \u003curl\u003ehttps://maven.pkg.github.com/OWNER/*\u003c/url\u003e\n                    \u003csnapshots\u003e\n                        \u003cenabled\u003etrue\u003c/enabled\u003e\n                    \u003c/snapshots\u003e\n                \u003c/repository\u003e\n            \u003c/repositories\u003e\n        \u003c/profile\u003e\n    \u003c/profiles\u003e\n\n    \u003cactiveProfiles\u003e\n        \u003cactiveProfile\u003egithub\u003c/activeProfile\u003e\n    \u003c/activeProfiles\u003e\n\n\u003c/settings\u003e\n```\n\n### Perform release\n\nTo perform a release, decide which version to increment and run the following Makefile target:\n\n```shell\nmake release-\u003cpatch|minor|major\u003e\n```\n\n#### Continuing a failed release\n\nIf the `perform:prepare` Maven target failed, you can re-run the whole release again from beginning.\n\nIf the `perform:release` Maven target failed, you can resume it by:\n\n```shell\ncd target/checkout\nmvn deploy -P docker-images-push -rf clearflask-\u003cmodule-to-resume\u003e\n```\n\n# Security Policy\n\n## Reporting a Vulnerability\n\nPlease report to security@clearflask.com for all vulnerabilities or questions regarding security. We will issue a bounty\nfor useful vulnerabilities to pay for your contribution, however we do not have a set standard on the amount and type of\nvulnerabilities at this time.\n","funding_links":[],"categories":["others","TypeScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclearflask%2Fclearflask","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclearflask%2Fclearflask","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclearflask%2Fclearflask/lists"}