{"id":21487527,"url":"https://github.com/dtinth/eventpop-ticket-gateway","last_synced_at":"2025-07-15T15:31:20.791Z","repository":{"id":62112117,"uuid":"298589245","full_name":"dtinth/eventpop-ticket-gateway","owner":"dtinth","description":"A gateway that lets Eventpop ticket holders authenticate themselves","archived":false,"fork":false,"pushed_at":"2022-10-26T14:03:04.000Z","size":66,"stargazers_count":4,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-05-02T06:07:08.125Z","etag":null,"topics":["jwt","oauth2","typescript","vercel"],"latest_commit_sha":null,"homepage":"https://eventpop-ticket-gateway.vercel.app","language":"TypeScript","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/dtinth.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":"2020-09-25T14:01:50.000Z","updated_at":"2022-11-07T09:30:22.000Z","dependencies_parsed_at":"2022-10-26T15:45:15.074Z","dependency_job_id":null,"html_url":"https://github.com/dtinth/eventpop-ticket-gateway","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/dtinth%2Feventpop-ticket-gateway","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dtinth%2Feventpop-ticket-gateway/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dtinth%2Feventpop-ticket-gateway/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dtinth%2Feventpop-ticket-gateway/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dtinth","download_url":"https://codeload.github.com/dtinth/eventpop-ticket-gateway/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226048084,"owners_count":17565458,"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":["jwt","oauth2","typescript","vercel"],"created_at":"2024-11-23T13:29:26.731Z","updated_at":"2024-11-23T13:29:27.352Z","avatar_url":"https://github.com/dtinth.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# eventpop-ticket-gateway\n\nA gateway that lets Eventpop ticket holders authenticate themselves.\n\nThis gateway is built for [Creatorsgarten](https://creatorsgarten.org/) team,\nwho organizes many events that covers multiple themes, organized by different\npeople, but under the same umbrella.\n\nThis gateway provides a way for developers to provide a \"Authenticate using\nEventpop Ticket\" experience without needing to implement the whole OAuth2 flow.\n\nThe ticket gateway uses RSA signatures to sign the ID token, so consumers\ncan verify the authenticity of the token without having to share `client_secret`,\n`access_token`, or any other secret. Just use the public key [(below)][pk] to\nverify the JWT.\n\n| Without eventpop-ticket-gateway | With eventpop-ticket-gateway |\n| ------------------------------- | ---------------------------- |\n| `client_secret` has to be shared with each developer for them to develop Eventpop integrations. | No need to share `client_secret`. |\n| Developer must make multiple API calls to Eventpop API and develop UIs to handle the sign-in and ticket selection flow. | No API calls — just redirect user to the gateway and it redirects user back to your app with a JWT. Pre-built UIs for ticket selection is provided. |\n\n[pk]: #3-extract-and-validate-the-id-token\n\n## Why\n\nEventpop’s API has **User Authentication Flow**. However, a user can have\nmultiple tickets for multiple events.\n\nUsually, when integrating with Eventpop, I find that most of the time I care\nabout a single ticket for a single event. That means each time I integrate with\nEventpop I have to implement the following logic:\n\n1. If user doesn’t have a ticket for the current event, they cannot continue.\n2. If user has multiple tickets for the current event, let them pick which one\n   to use.\n\nThis repository implements the so-called **Ticket Authentication Flow** which\ntakes care of the above requirements. Once user has authenticated and selected a\nticket, we (the Ticket Gateway) send the user back to the application along with\na [JWT ID token](https://auth0.com/docs/tokens/id-tokens) signed with an RS256\nprivate key. The system can verify the validity of the ID token by checking it\nagainst the [public key][pk].\n\n## Ticket Authentication Flow Sequence Diagram\n\n![](http://www.plantuml.com/plantuml/svg/bP91JyCm38Nl_HLMkO04hRG34fF6Dc0Wxd168RMQg5bS9HxL-FKqwIWRb4wxv61_UTRpyyApSBnPc-JLeuEhMrZMjT5Ii2OBKp1KQflirG8IqIcK14pmecM534-2iH7RNYOzhASjdpiij4F9cUArcUC7MdukPZVNaqdo1_yzPXNeckf-m7SX29FOiCh3Gqv_OjBtVbJwvdn8OOj-w5D15Y-XTkZR5h3I7b991QOd6fV2c7SXgyvuK9XbMJPaUi0MKuKswUl38uIKwFrRP8_fbiWTuCzt6LmSa-UE7uj9AYAFq2WjrOuFM_AwjA0jD9hLs8wMT_SFgyUn0OSnHASn1rQuVxJ_77BUBlmiVeghNw0jsgl_0W00)\n\n## How to integrate\n\n### 1. Redirect user to ticket gateway\n\nConstruct a URL to the ticket gateway’s `redirect.html` with the following query params:\n\n- `eventId` Eventpop event ID.\n- `target` The target URL to redirect to. Should contain an `%s` in it.\n\nExample:\n\n```js\nconst url = 'https://eventpop-ticket-gateway.vercel.app/redirect.html?' + new URLSearchParams({\n  eventId: '13089',\n  target: 'https://httpbin.org/anything?id_token=%s'\n})\nconsole.log(url)\n```\n\nGenerates the following URL:\n\n\u003e \u003chttps://eventpop-ticket-gateway.vercel.app/redirect.html?eventId=13089\u0026target=https%3A%2F%2Fhttpbin.org%2Fanything%3Fid_token%3D%25s\u003e\n\n### 2. User logs in with Eventpop and selects a ticket\n\n![image](https://user-images.githubusercontent.com/193136/178738038-a490777c-71f9-41ab-8a57-d64294bf56e5.png)\n\nAfter user select ticket, they will be redirected to the URL specified in `target` param. The `%s` will be replaced by the **ID token**.\n\n### 3. Extract and validate the ID token\n\nExtract the ID token from the URL. Here is an example ID token:\n\n```\neyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0aWNrZXRJZCI6NDc4MDU2OSwiZXZlbnRJZCI6MTMwODksImZpcnN0bmFtZSI6IlRoYWkiLCJsYXN0bmFtZSI6IlBhbmdzYWt1bHlhbm9udCIsImVtYWlsIjoiW3JlZGFjdGVkXUBnbWFpbC5jb20iLCJyZWZlcmVuY2VDb2RlIjoiUkVEQUNUIiwidGlja2V0VHlwZSI6IuC4muC4seC4leC4o-C5gOC4guC4ouC5iOC4hyIsInRhcmdldCI6Imh0dHBzOi8vaHR0cGJpbi5vcmcvYW55dGhpbmc_aWRfdG9rZW49JXMiLCJpYXQiOjE2NTc3MTY2ODksImV4cCI6MTY1Nzc1MjY4OX0.RDPOgFg8XTs2JkcfVEF6p8_8dWBSGN73dC3i0JyZM6fXtDukurKHff3T3mWYkdLZbt3wDt760IcynyhQhEVLxhjVzczmwRvFU5BH0c87XIwF18tpRXH8PbNG9XgNduP6MhoLNIxXcrQWMDcj4QDiC0BfTyd4EZNdAwolAYzytxyjMYskBb3w61y8u4ncQ2xdipfbbwx8zAYMcs_1IvryJWITIM5Fi7HmTI_oldt93lNgBA5mQ1cKpHSj0jqkq67rVMirFrDrmhmTHX7OKALBHZwk734hNqMrZIWIdjYBLZ-fP_ctDYwwOo5e5qbTw9Hq--mKlDA-uqS75GDX0_kQ2Q\n```\n\nVerify its signature using the following public key:\n\n```\n-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8GO2/OpcRMCJ150DyObi\nQkN54M1ACoDN+CyRzCuY4o3yFPYfIFnhwTFX622SIDrqv9HDoIKwT1XitIsToyBH\nsSfET/iukcHhqjQnowdQAvxmgK4gSDxipHcbBd1c2Qfjwfkfj4X3CfR9ronA1HYe\n2vICBpwcyiJTyicljuyq1kvFWG7S24iugh0DJ9wuHo/rF3gmWlU9/5TTMKR+GLxI\nnRAFIpN5DfdVYbj6foLelq2r8KdMtQZzzt6nBR7RcraPSuidHWKkYR8KJrTmZn4z\nJW6iZD9S9gdyfRQZMXu1TMYq7B9D25EE8lceY/c5KSVSvKcrvIcqTJu02T+iOrat\nswIDAQAB\n-----END PUBLIC KEY-----\n```\n\nThen, when decoded, you will find the following claims:\n\n```json\n{\n  \"ticketId\": 4780569,\n  \"eventId\": 13089,\n  \"firstname\": \"Thai\",\n  \"lastname\": \"Pangsakulyanont\",\n  \"email\": \"[redacted]@gmail.com\",\n  \"referenceCode\": \"REDACT\",\n  \"ticketType\": \"บัตรเขย่ง\",\n  \"target\": \"https://httpbin.org/anything?id_token=%s\",\n  \"iat\": 1657716689,\n  \"exp\": 1657752689\n}\n```\n\nPerform these checks:\n\n| Claim | Condition |\n| ----- | --------- |\n| `eventId` | Should match the event ID that you are integrating. |\n| `ticketType` | Should be the name of the ticket type that you accept. Skip this check if you intend to a accept all ticket types. |\n| `aud` or `target` | Should match the target URL that you provided in step 1. |\n| `exp` | Should be greater than the current Unix timestamp. |\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdtinth%2Feventpop-ticket-gateway","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdtinth%2Feventpop-ticket-gateway","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdtinth%2Feventpop-ticket-gateway/lists"}