{"id":17346135,"url":"https://github.com/rushiimachine/timezonedb","last_synced_at":"2025-04-14T20:50:41.050Z","repository":{"id":49798130,"uuid":"518152023","full_name":"rushiiMachine/TimezoneDB","owner":"rushiiMachine","description":"The backend of the Aliucord/Vencord's Timezones plugins","archived":false,"fork":false,"pushed_at":"2024-06-27T19:26:35.000Z","size":308,"stargazers_count":9,"open_issues_count":1,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-06T06:14:56.294Z","etag":null,"topics":["discord-client-mod","rocket","rust"],"latest_commit_sha":null,"homepage":"https://timezonedb.catvibers.me","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rushiiMachine.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-07-26T17:15:17.000Z","updated_at":"2025-03-13T03:01:13.000Z","dependencies_parsed_at":"2023-02-17T09:01:33.336Z","dependency_job_id":null,"html_url":"https://github.com/rushiiMachine/TimezoneDB","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rushiiMachine%2FTimezoneDB","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rushiiMachine%2FTimezoneDB/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rushiiMachine%2FTimezoneDB/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rushiiMachine%2FTimezoneDB/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rushiiMachine","download_url":"https://codeload.github.com/rushiiMachine/TimezoneDB/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248960916,"owners_count":21189990,"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":["discord-client-mod","rocket","rust"],"created_at":"2024-10-15T16:44:39.549Z","updated_at":"2025-04-14T20:50:40.984Z","avatar_url":"https://github.com/rushiiMachine.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# TimezoneDB ![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2FDiamondMiner88%2FTimezoneDB\u0026count_bg=%2379C83D\u0026title_bg=%23555555\u0026icon=github.svg\u0026icon_color=%23E7E7E7\u0026title=views\u0026edge_flat=true)\r\n\r\nA rewrite for the backend of the BetterDiscord/Aliucord's Timezones plugins.\r\n\r\n### Note for Plugin Developers\r\n\r\nWhen linking to the host website, please use `\u003cHOST\u003e/?client_mod=\u003cYOUR_MOD_NAME\u003e` instead of just the base URL. This is\r\nfor internal analytics. When calling the API directly, please provide a detailed User-Agent header that describes where\r\nthe request is from, for example `Vencord/1.0.0`. Adding on to this, if you are setting the user's public timezone\r\nmanually, please do provide the `clientMod` field as well.\r\n\r\n# Setup\r\n\r\nBefore you build, create a new Discord application in the [portal](https://discord.com/developers/applications).\r\nYou should make a redirect uri in the OAuth tab that is equal to `{HOST}/api/auth`, `{HOST}` being the environment\r\nvariable below. Copy the secret and id from the OAuth tab to set as environment variables, shown below.\r\n\r\n### Environment variables\r\n\r\n| PORT             | TYPE   | Default                                              | Description                                                                  | \r\n|------------------|--------|------------------------------------------------------|------------------------------------------------------------------------------|\r\n| `PORT`           | u16    | 8000 (unmodifiable in debug)                         | The port to serve the app on                                                 |\r\n| `HOST`           | String | crash in release, `http://localhost:{PORT}` in debug | The host string as the base section of the Discord redirect.                 |\r\n| `DISCORD_ID`     | u64    | crash                                                | The app client id from the OAuth section of the portal.                      |\r\n| `DISCORD_SECRET` | String | crash                                                | The app secret from the **OAuth section** of the portal.                     |\r\n| `JWT_SECRET`     | any    | crash in release, `timezone_db` in debug build       | Any value used for encrypting JWT tokens.                                    |\r\n| `POSTGRES_URL`   | String | crash                                                | The full [connection string](https://stackoverflow.com/a/20722229/13964629). |\r\n\r\n### Manual\r\n\r\n```sh\r\n# Manually:\r\n$ pnpm install\r\n$ pnpm build\r\n$ cargo build --release\r\n$ export PORT=\u003cport\u003e;DISCORD_ID=\u003cid\u003e;DISCORD_SECRET=\u003csecret\u003e;HOST=\u003chost\u003e;JWT_SECRET=\u003ckey\u003ePOSTGRES_URL=\u003cconnection_string\u003e;\r\n$ ./target/release/timezone_db\r\n```\r\n\r\n## Development\r\n\r\nDue to rocket not supporting proxying requests, I've had to do it the other way around in development; interface through\r\nCRA and proxy unknown requests to the backend server. This leads to a few weird issues like any 404s from either end\r\nwill end up serving index.html from CRA. However, the rust portion is built in release mode, the React app will be\r\nbundled with the executable and served using rocket.\r\n\r\n1. Clone repo\r\n2. Install pnpm \u0026 rust toolchain \u0026 perl (for openssl-sys)\r\n3. Pull dependencies: `pnpm install`\r\n4. Launch postgres: `docker run --name test-postgres -e POSTGRES_PASSWORD=password -d -p 5432:5432 postgres`\r\n5. Run\r\n   backend: `DISCORD_ID=\u003cid\u003e;DISCORD_SECRET=\u003csecret\u003e;POSTGRES_URL=\"postgres://postgres:password@localhost:5432/postgres\" cargo run`\r\n6. Run frontend: `pnpm start`\r\n7. App is accessible here: `http://localhost:3000`\r\n\r\n## API\r\nAuthentication is done through a JWT token in the `loginInfo` cookie that is sent with every request.\r\n\r\n### GET `/api` (auth optional)\r\nResponse: `{ loggedIn: bool }`\r\n\r\n### GET `/api/auth`\r\nRedirects to the currently configured Discord OAuth url.\r\n\r\n### GET `/api/auth?error=access_denied`\r\nRedirects to `/`\r\n\r\n### GET `/api/auth?code=\u003ccode\u003e`\r\nAuthenticates the user with JWT, sets the cookie and redirects to `/`\r\n\r\n### GET `/api/auth/logout`\r\nRemoves the auth cookie and redirects to `/`\r\n\r\n### GET `/api/user` (auth required)\r\nRedirects to `/api/user/\u003ccurrent_id\u003e` based on the JWT otherwise throws 401 if no auth.\r\n\r\n### GET `/api/user/\u003cid\u003e`\r\nGets the data from the DB and returns json. Returns 404 if no user with that id is found. Returns a user object.\r\n\r\n#### User\r\n| Field      | Type   | Description                                                       |\r\n|------------|--------|-------------------------------------------------------------------|\r\n| userId     | string | Discord user snowflake id.                                        |\r\n| timezoneId | string | The timezone name.                                                |\r\n| timezone   | string | The calculated UTC offset of the timezone. Ex. `+5`, `-5` `+5:30` |\r\n\r\n### POST `/api/user/bulk`\r\nGets multiple users at the same time. Body is an array of string ids.\r\nReturns an object of `{\u003cuserId\u003e: null | \u003cuser\u003e}`\r\n\r\n### GET `/api/user/\u003cid\u003e/exists`\r\nChecks whether a user is stored in the DB. Returns 200/404 status code.\r\n\r\n### DELETE `/api/user` (auth required)\r\nDeletes the current user from the db completely.\r\n\r\n### PUT `/api/user` (auth required)\r\nUpdates the current user's data. Missing field = no update.\r\n\r\nBody:\r\n\r\n| Field      | Type    | Description                                  |\r\n|------------|---------|----------------------------------------------|\r\n| timezone?  | string? | A new valid timezone name.                   |\r\n| clientMod? | string? | The client mod that this user uses (if any). |\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frushiimachine%2Ftimezonedb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frushiimachine%2Ftimezonedb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frushiimachine%2Ftimezonedb/lists"}