{"id":18613580,"url":"https://github.com/aabbtree77/auth-starter-backend","last_synced_at":"2025-05-07T02:43:33.159Z","repository":{"id":246067455,"uuid":"819950233","full_name":"aabbtree77/auth-starter-backend","owner":"aabbtree77","description":"Backend for a complete session-based user authentication: Bun, Hono, Drizzle, SQLite.","archived":false,"fork":false,"pushed_at":"2025-03-16T21:53:16.000Z","size":25,"stargazers_count":2,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-31T05:32:54.481Z","etag":null,"topics":["authentication","authorization","backend-api","bun","cookie","cors","credentials","crud","drizzle","hono","minimalism","ngrok","security","session","sqlite","typescript","user-password","xss"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/aabbtree77.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}},"created_at":"2024-06-25T13:54:32.000Z","updated_at":"2025-03-16T21:53:18.000Z","dependencies_parsed_at":"2025-03-06T19:24:51.493Z","dependency_job_id":"7bad15b2-770e-484c-b8f9-0bd256f31883","html_url":"https://github.com/aabbtree77/auth-starter-backend","commit_stats":null,"previous_names":["aabbtree77/auth-starter-backend"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aabbtree77%2Fauth-starter-backend","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aabbtree77%2Fauth-starter-backend/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aabbtree77%2Fauth-starter-backend/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aabbtree77%2Fauth-starter-backend/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aabbtree77","download_url":"https://codeload.github.com/aabbtree77/auth-starter-backend/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252802608,"owners_count":21806537,"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":["authentication","authorization","backend-api","bun","cookie","cors","credentials","crud","drizzle","hono","minimalism","ngrok","security","session","sqlite","typescript","user-password","xss"],"created_at":"2024-11-07T03:22:48.065Z","updated_at":"2025-05-07T02:43:33.148Z","avatar_url":"https://github.com/aabbtree77.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003e \"Sad thoughts come to me when I look in a bookcase full of biochemistry books. I realize that the bookcase will last much longer than the contents of the books in it.\" \n\u003e\n\u003e — *Bolesław Skarżyński (1901-1963)*\n\n# Introduction\n\nThis is the backend part of a session-based user name and password authentication with a [frontend](https://github.com/aabbtree77/auth-starter-frontend).\n\nThe stack is Bun, SQLite via Drizzle, Hono, TypeScript. \n\nOpen three terminal windows:\n\nTerminal 1:\n\n```sh\nbun install\nbun run dev\n```\n\nTerminal 2:\n\n```sh\nbun run db:generate\nbun run db:push\nbun run db:studio\n```\n\nTerminal 3:\n\ncd into the cloned frontend part and run TypeScript as documented in [README.md](https://github.com/aabbtree77/auth-starter-frontend).\n\n# Debugging\n\nDelete the tables with the browser GUI in Drizzle Studio. Use `bun run db:generate` if you adjust the tables/schema. `bun run db:push` creates and updates the actual database file in `/storage`. If some weird problems appear, delete the `*.db` file inside that folder. This is how I handle \"migrations\" ;). \n\nI use `bun:sqlite` instead of `better-sqlite3`, but the latter is still needed by drizzle-kit, so better-sqlite3 is in `package.json`, but not in the code. See [this issue](https://github.com/drizzle-team/drizzle-orm/issues/1520).\n\nIf you plan on changing the database, pay attention at the time zones and TypeScript's Date.Now(). `src/utils/sessionhelper.ts` appends `Z` to enforce the UTC when extracting the session expiry from the session table. Without such care, storing and reading may not result in the same value, and with the use of Date.Now() one can easily get some weird bugs where everything works only for longer session expiration times. \n\nIn my case, I am 3 hours ahead of the UTC, and could not see any problems when setting a session expiry to 5 hours, at first. It turned out that the program had a bug as it would subtract 3 hours from `session.expiresAt` due to UTC not enforced, killing a session instantly for the TTL values smaller or equal to 3 hours.\n\n# Security\n\nThis is a bare-bones minimal authentication, use it at your own risk. \n\nNotice that there is no `.env` inside `.gitignore`. You may need to change that.\n\nI could not set any cookies at first, but ChatGPT 4o helped to solve the problem admirably.\n\nIt involves using Hono CORS middleware with the frontend URL and `credentials: true`:\n\n```ts\napp.use(\n  cors({\n    origin: 'http://localhost:5173',\n    allowHeaders: ['Content-Type'],\n    allowMethods: ['GET,HEAD,PUT,PATCH,POST,DELETE'],\n    credentials: true,\n  })\n);\n```\n\nAlso, the fetch API at the frontend always needs an extra line\n\n```\ncredentials: 'include'\n```\n\nFinally, there is a difference between the local (dev) and prod modes not shown in this code (which is tested only with the local development).\n\nFor the production mode, the cookie creation in Hono would need to be set this way:\n\n```\nsetCookie(c, 'sessionId', sessionId, {\n    path: '/',\n    maxAge: ttlSeconds,\n    httpOnly: true,\n    sameSite: 'None', // Use 'None' for cross-origin requests\n    secure: true, // Requires HTTPS\n  });\n```\n\nLocally, `sameSite: Lax` while `secure: true` needs to be removed due to HTTP, as in this code. \n\nIt is possible to test HTTPS locally and retain `secure: true`, but one needs to install `ngrok` and forward `localhost:3000` via\n\n```sh\nngrok http 3000\n```\n\nNotice that `httpOnly: true` works both locally and globally. It blocks any client Js code access to a cookie value via `document.cookie`, which limits the XSS attacks.\n\n# Further Notes\n\n- SQLite has no date and uuid types and they say it is worse at \"horizontal scaling\" when compared to PostgreSQL. I am not pedantic and advanced enough to worry about such matters.\n\n- Bun is replacable with Node, Hono with Express, SQLite with PostgreSQL. Redo this with ChatGPT/DeepSeek file by file for your use case in a separate repo instead of building a generic caboodle.\n\n- Push this further or jump to something ready-made such as PocketBase or Better Auth?!\n\n# References\n\n[The 2023 State of JavaScript survey](https://2023.stateofjs.com/en-US/usage/)\n\n[Complex Schema Design with Drizzle ORM. youtube, 2024](https://www.youtube.com/watch?v=vLze97zZKsU\u0026t=2305s)\n\n[You should learn Drizzle, the TypeScript SQL ORM. Syntax podcast #721, 2024](https://syntax.fm/show/721/you-should-learn-drizzle-the-typescript-sql-orm)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faabbtree77%2Fauth-starter-backend","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faabbtree77%2Fauth-starter-backend","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faabbtree77%2Fauth-starter-backend/lists"}