{"id":17788711,"url":"https://github.com/devel0/example-webapp-with-auth","last_synced_at":"2026-04-18T04:32:50.054Z","repository":{"id":242633947,"uuid":"810111404","full_name":"devel0/example-webapp-with-auth","owner":"devel0","description":"example of webapp with c# aspnet core backend and typescript angular/react frontend with httponly jwt auth","archived":false,"fork":false,"pushed_at":"2026-02-01T09:24:10.000Z","size":12301,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-01T19:50:19.486Z","etag":null,"topics":["angular","aspnetcore","httponly-cookie","https","jwt","material-ui","react","react-router-dom","static-files","vite","zustand"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/devel0.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-06-04T04:24:31.000Z","updated_at":"2026-02-01T09:23:44.000Z","dependencies_parsed_at":"2024-08-14T08:46:23.876Z","dependency_job_id":"22361c75-5486-4039-baa3-f675f459441d","html_url":"https://github.com/devel0/example-webapp-with-auth","commit_stats":null,"previous_names":["devel0/example-webapp-with-auth"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/devel0/example-webapp-with-auth","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devel0%2Fexample-webapp-with-auth","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devel0%2Fexample-webapp-with-auth/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devel0%2Fexample-webapp-with-auth/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devel0%2Fexample-webapp-with-auth/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/devel0","download_url":"https://codeload.github.com/devel0/example-webapp-with-auth/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devel0%2Fexample-webapp-with-auth/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31956939,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T00:39:45.007Z","status":"online","status_checked_at":"2026-04-18T02:00:07.018Z","response_time":103,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["angular","aspnetcore","httponly-cookie","https","jwt","material-ui","react","react-router-dom","static-files","vite","zustand"],"created_at":"2024-10-27T10:20:55.521Z","updated_at":"2026-04-18T04:32:50.045Z","avatar_url":"https://github.com/devel0.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# example-webapp-with-auth\n\n## features\n\n- Security\n  - development using https acme wildcard cert ( alternatively use [selfsigned][1] )\n  - authorization through JWT cookie `secure`, `httponly`, `samesite strict`\n  - webapi with roles authorization\n- Developer friendly\n  - breakpoints works for c# backend and typescript angular/react frontend from the same vscode session\n- [Backend][12]\n  - c# asp net core\n  - configuration\n    - development `user-secrets`\n    - appsettings ( autoreload on change )\n    - production environment variables\n- Frontend\n  - [angular][10]\n    - openapi typescript/angular api services generated from backend swagger endpoint\n    - layout with responsive menu\n    - websocket alive check\n    - authguard protected pages routes\n    - login / logout ( reset lost password through email link )\n    - user manager\n    - datagrid pagination with server side sort/filter\n    - light/dark theme scss styles\n    - snacks    \n  - [react][11]\n    - openapi typescript/axios api generated from backend swagger endpoint\n    - layout with responsive menu\n    - websocket alive check\n    - protected pages with react router dom\n    - zustand global services\n    - datagrid pagination with server side sort/filter\n    - login / logout / reset lost password through email link\n    - light/dark theme scss styles\n    - snacks    \n\n## quickstart\n\n- clone repository\n\n```sh\ngit clone https://github.com/devel0/example-webapp-with-auth.git\ncd example-webapp-with-auth\n```\n\n- option 1 : angular frontend\n\n```sh\ngit checkout frontend/angular\n```\n\n- option 2 : react frontend\n\n```sh\ngit checkout frontend/react\n```\n\n- start development environment\n\n```sh\ncode .\n```\n\n- restore exec permissions on helper scripts\n\n```sh\nsource misc/restore-permissions.sh\n```\n\n- configure backend development variables\n\n```sh\ncd src/backend\n\ndotnet user-secrets init\n\n# change following as needed\nSEED_ADMIN_EMAIL=some@domain.com\nSEED_ADMIN_PASS=\"SEED_ADMIN_SECRET\"\nDB_PROVIDER=\"Postgres\"\nDB_CONN_STRING=\"Host=localhost; Database=DBNAME; Username=DBUSER; Password=DBPASS\"\n\nJWTKEY=\"$(openssl rand -hex 32)\"\n\ndotnet user-secrets set \"AppConfig:Auth:Jwt:Key\" \"$JWTKEY\"\n\ndotnet user-secrets set \"AppConfig:Database:Seed:Users:0:Username\" \"admin\"\ndotnet user-secrets set \"AppConfig:Database:Seed:Users:0:Email\" \"$SEED_ADMIN_EMAIL\"\ndotnet user-secrets set \"AppConfig:Database:Seed:Users:0:Password\" \"$SEED_ADMIN_PASS\"\ndotnet user-secrets set \"AppConfig:Database:Seed:Users:0:Roles:0\" \"admin\"\n\ndotnet user-secrets set \"AppConfig:Database:Connections:0:Name\" \"Development\"\ndotnet user-secrets set \"AppConfig:Database:Connections:0:ConnectionString\" \"$DB_CONN_STRING\"\ndotnet user-secrets set \"AppConfig:Database:Connections:0:Provider\" \"$DB_PROVIDER\"\n\ndotnet user-secrets set \"AppConfig:Database:ConnectionName\" \"Development\"\n\ncd ../..\n```\n\n- adjust [BULK_SLICE_CNT][13] ( currently 1M rows generated on first datagrid load )\n\n- start backend choosing C-S-P `Debug: Select and Start Debugging` then `BACKEND`\n\n- start frontend by issueing\n\n```sh\n./run-frontend.sh\n```\n\n- start frontend debugger C-S-P `Debug: Select and Start Debugging` then `FRONTEND` ; this will open chrome to the named url and attaches the debugger\n\n- to make things works with https acme cert you need a domain to set a CNAME record and certbot as described [here][2]\n\n- then edit hosts `sudo /etc/hosts` like following in order to resolve name locally\n\n```\n127.0.0.1   dev-webapp-test.searchathing.com\n```\n\n- finally set nginx `sudo apt install nginx` by linking the conf\n\n```sh\ncd /etc/nginx/conf.d\nln -s ~/opensource/example-webapp-with-auth/deploy/nginx/dev/webapp-test.conf\nservice nginx reload\n```\n\n## development settings for lost password recovery\n\n```sh\ncd src/backend\n\n# MAILSERVER_SECURITY can be \"Tls\" or \"Ssl\" or \"Auto\" or \"None\"\n\ndotnet user-secrets set \"EmailServer:SmtpServerName\" \"$MAILSERVER_HOSTNAME\"\ndotnet user-secrets set \"EmailServer:SmtpServerPort\" \"$MAILSERVER_PORT\"\ndotnet user-secrets set \"EmailServer:Security\" \"$MAILSERVER_SECURITY\"\ndotnet user-secrets set \"EmailServer:Username\" \"$MAILSERVER_USER_EMAIL\"\ndotnet user-secrets set \"EmailServer:Password\" \"$MAILSERVER_USER_PASSWORD\"\n```\n\n## development setting for unit tests\n\nwhen run backend unit tests with `dotnet test` the system will search for a configured db connection named \"UnitTest\"\n\n:warning: use a separate db because it will be destroyed when test executes\n\n```sh\ncd src/backend\n\ndotnet user-secrets set \"AppConfig:Database:Connections:1:Name\" \"UnitTest\"\ndotnet user-secrets set \"AppConfig:Database:Connections:1:ConnectionString\" \"$UNIT_TEST_DB_CONN_STRING\"\ndotnet user-secrets set \"AppConfig:Database:Connections:1:Provider\" \"$DB_PROVIDER\"\n```\n\nnote: to avoid `terminating connection due to administrator command` with postgres db in unit test append `; POOLING=False` to the connection string [ref][14]\n\n## deployment\n\na script to automate publish on production server is available\n\n```sh\n./publish -h sshname -sn test.searchathing.com -id mytest -sd searchathing.com\n```\n\nwhere\n- `-h` is a configured `~/.ssh/config` entry to allow to enter with a public key to a server within root user\n- `-sn` is the application server hostname\n- `-id` is a unique application id to allow more app on the same server\n- `-sd` is the domain name where app run\n\npublished files and folders\n\n| folder                                      | description                                                                                   |\n| ------------------------------------------- | --------------------------------------------------------------------------------------------- |\n| `/root/security/mytest.env`                 | copy (if not already exists) of [webapp.env][6]                                               |\n| `/root/deploy/mytest`                       | rsync of [deploy][3] folder                                                                   |\n| `/srv/mytest/bin`                           | rsync of self contained production `src/backend/bin/Release/net9.0/linux-x64/publish/` folder |\n| `/etc/system/systemd/mytest-webapp.service` | copy (if not already exists) of [webapp.service][4]                                           |\n| `/etc/nginx/conf.d/mytest-webapp.conf`      | copy (if not already exists) of [webapp.conf][5]                                              |\n\nprerequisites on server side:\n\n```sh\napt install openssh-server rsync nginx\n\n# to run the backend service as user\nuseradd -m user\n```\n\nediting configuration and logging production\n\n- edit `/root/security/mytest.conf` setting variables accordingly to your production setup ( if not used EmailServer variables comment out with `#` )\n\nto view backend service log\n\n```sh\njournalctl -u mytest-webapp -f\n```\n\nto restart backend service\n\n```sh\nservice mytest-webapp restart\n```\n\n## openapi generator\n\nuse provided script [gen-api.sh][9] to generate frontend api from the backend swagger openapi ; this script will detect if angular or react frontend and retrieve corresponding hostname information from environment or vite depending\n\n## developer documentation\n\n- [backend][12]\n- frontend\n  - [angular][10]\n  - [react][11]\n\n[1]: https://github.com/devel0/knowledge/blob/cf1f477a4ccf898d7299dab4daa71ebcf049172f/doc/self-signed-cert.md\n[2]: https://github.com/devel0/knowledge/blob/cf1f477a4ccf898d7299dab4daa71ebcf049172f/doc/letsencrypt-acme-dns.md\n[3]: ./deploy\n[4]: ./deploy/service/webapp.service\n[5]: ./deploy/nginx/prod/webapp.conf\n[6]: ./deploy/webapp.env\n[9]: ./gen-api.sh\n[10]: https://github.com/devel0/example-webapp-with-auth/tree/frontend/angular/doc/frontend.md\n[11]: https://github.com/devel0/example-webapp-with-auth/tree/frontend/react/doc/frontend.md\n[12]: ./doc/backend.md\n[13]: https://github.com/devel0/example-webapp-with-auth/blob/b4ba4c5556e4b3739525b33600b2d6721dad6ecb/src/backend/Services/Fake/FakeService.cs#L36-L37\n[14]: https://stackoverflow.com/a/72602642/5521766\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevel0%2Fexample-webapp-with-auth","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevel0%2Fexample-webapp-with-auth","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevel0%2Fexample-webapp-with-auth/lists"}