{"id":17723266,"url":"https://github.com/aaronpk/meetable","last_synced_at":"2025-04-12T12:02:10.306Z","repository":{"id":37585461,"uuid":"228271344","full_name":"aaronpk/Meetable","owner":"aaronpk","description":"an event listing website","archived":false,"fork":false,"pushed_at":"2024-08-07T18:51:30.000Z","size":3842,"stargazers_count":102,"open_issues_count":34,"forks_count":10,"subscribers_count":4,"default_branch":"main","last_synced_at":"2024-08-08T15:15:01.159Z","etag":null,"topics":["aggregator","events","indieweb"],"latest_commit_sha":null,"homepage":"https://meetable.org","language":"PHP","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/aaronpk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE.txt","code_of_conduct":".github/CODE_OF_CONDUCT.md","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},"funding":{"open_collective":"indieweb","custom":"https://aaronparecki.com/tip/5"}},"created_at":"2019-12-16T00:11:21.000Z","updated_at":"2024-08-07T18:51:35.000Z","dependencies_parsed_at":"2023-01-29T17:31:12.786Z","dependency_job_id":"be5cf841-e408-4870-8908-24c4dc2acefe","html_url":"https://github.com/aaronpk/Meetable","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/aaronpk%2FMeetable","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaronpk%2FMeetable/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaronpk%2FMeetable/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aaronpk%2FMeetable/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aaronpk","download_url":"https://codeload.github.com/aaronpk/Meetable/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248565090,"owners_count":21125415,"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":["aggregator","events","indieweb"],"created_at":"2024-10-25T15:42:22.984Z","updated_at":"2025-04-12T12:02:10.233Z","avatar_url":"https://github.com/aaronpk.png","language":"PHP","funding_links":["https://opencollective.com/indieweb","https://aaronparecki.com/tip/5"],"categories":[],"sub_categories":[],"readme":"# Meetable\n\n[![Deploy](https://www.herokucdn.com/deploy/button.svg)](https://heroku.com/deploy)\n\nMeetable is a minimal events aggregator website.\n\nYou can see a live version of this project at:\n\n* https://events.indieweb.org\n* https://events.oauth.net\n\n## Features\n\n* **Discovery** List of upcoming events on the home page, and archive view of past events.\n* **Tags** Events can have one or more tags. Commonly-used tags are shown on the home page as well as the \"discover\" page.\n* **iCal feeds** All lists of events have an iCal feed (home page, tag pages, etc) so you can subscribe to them in an external calendar.\n* **Add to Calendar** Events have an \"Add to Calendar\" link that exports either an iCal file or links to Google Calendar.\n\n### Event Pages\n\nEvents have a permalink that contains\n\n* cover photo\n* event name, date/time and location details\n* a link to an external website and ticket URL\n* a description of the event, which supports markdown and basic HTML formatting\n* a link to a timezone converter\n* RSVPs (an RSVP button appears for logged-in users)\n* photos, blog posts, and notes about the event\n\nWhen logged in, you can add photos directly to an event page. Event pages also accept [webmentions](https://webmention.net) so that people can add photos and notes to the page from their own websites.\n\n\n## Setup\n\n### Requirements\n\n* PHP 8.2+\n* [Composer](https://getcomposer.org)\n* MySQL/MariaDB\n* Optional: Redis\n\n### Installation\n\nThis project is based on [Laravel](https://laravel.com), so you can defer to their instructions if you encounter any issues.\n\nClone the source into a folder\n\n```bash\ngit clone https://github.com/aaronpk/Meetable.git\ncd Meetable\n```\n\nInstall the project's dependencies\n\n```bash\ncomposer install\n```\n\nMake sure the `storage` folder is writable by the web server.\n\n```bash\nsudo chown -R www-data: storage\n```\n\nCreate a database in your MySQL server, and create a user that has full access to the database. For example:\n\n```\nsudo mysql\n\u003e CREATE DATABASE meetable;\n\u003e GRANT ALL PRIVILEGES ON meetable.* TO 'meetable'@'127.0.0.1' IDENTIFIED BY 'some-password';\n```\n\nCopy `.env.example` to `.env` and fill it out following the instructions in the file.\n\n```bash\ncp .env.example .env\n```\n\nMost importantly, make sure you fill out the database section or the next step won't work.\n\nOnce you've configured everything in the `.env` file, you can run the migrations to set up the database.\n\n```bash\nphp artisan migrate\n```\n\nGenerate an application key:\n\n```\nphp artisan key:generate\n```\n\nIn a production system you'll want to make sure the background worker script is running:\n\n```bash\nphp artisan queue:listen\n```\n\nAlternatively, you can set up a cron job to run every minute which will process any jobs on the queue:\n\n```bash\nphp artisan queue:work --stop-when-empty\n```\n\n\n### Web Server\n\nConfigure your web server to serve the project's `public` folder from the domain name you've set up.\n\nFor nginx:\n\n```\nserver {\n  listen 443 ssl http2;\n  server_name  events.example.org;\n\n  ssl_certificate /etc/letsencrypt/live/events.example.org/fullchain.pem;\n  ssl_certificate_key /etc/letsencrypt/live/events.example.org/privkey.pem;\n\n  root /web/sites/events.example.org/public;\n\n  index index.php;\n  try_files $uri /index.php?$args;\n\n  location ~* \\.php$ {\n    fastcgi_pass    php-pool;\n    fastcgi_index   index.php;\n    fastcgi_split_path_info ^(.+\\.php)(.*)$;\n    include fastcgi_params;\n    fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;\n  }\n}\n```\n\nIf you're using the `local` storage driver to store uploaded images on disk, then make sure to symlink the storage folder:\n\n```\nphp artisan storage:link\n```\n\n\n### Authentication\n\nThere are a few different ways to handle user authentication depending on how you'd like to set it up. You can use GitHub so that GitHub users can log in, you can use your own custom authentication mechanism configured externally, either via OpenID Connect or by setting an HTTP header in your web server, or you can use the site in single-user mode with the admin user logging in with a passkey.\n\nIn your configuration file, you'll need to tell the project which authentication method to use:\n\n```bash\nAUTH_METHOD=\n```\n\nProvide one of the supported values for `AUTH_METHOD`:\n\n* `session` (passkey login)\n* `github`\n* `oidc`\n* `vouch`\n* `heroku`\n\nYou can choose whether or not you want a \"log in/out\" link to appear in the top navbar. When using single-sign-on with Vouch, it may be preferable to not have a log out button since that would log them out from more than just this website. For a single-user site where only you will be logging in to manage events, it is best to hide the login link so visitors don't try to log in. For a multi-user configuration, you can show both links.\n\n```bash\nAUTH_SHOW_LOGIN=true\nAUTH_SHOW_LOGOUT=false\n```\n\n#### Passkey Authentication\n\nIf you don't want to create any new dependencies when you set this up, you can use the built in passkey authentication to allow only yourself, the admin user, to log in.\n\nAfter you install the app, when you click \"Log In\", you'll be prompted to create your admin user account, specifying your email address and enrollling a passkey. From that point on, there is no way for users to be created in the web interface, and you'll need to log in with your passkey in the future.\n\nThis is a good option if you want to quickly set up the site and expect that you are the only one who will be logging in to manage the content.\n\nIf you expect multiple users to log in to manage the content, use one of the multi-user options below.\n\n\n#### GitHub Authentication\n\nWith GitHub authentication, any GitHub user will be able to log in to the application. You can also configure it to allow only certain users to log in if you wish, and any other user will see an error message if they try to log in.\n\nYou'll need to [create a GitHub OAuth application](https://github.com/settings/developers) and include the app's client ID and secret in the config file. In the GitHub app settings, set the callback URL to `https://events.example.org/auth/github`.\n\n```bash\nAUTH_METHOD=github\nGITHUB_CLIENT_ID=\nGITHUB_CLIENT_SECRET=\n```\n\nIf you want to restrict who can log in, define a space-separated list of usernames in the config file. If someone attempts to log in via GitHub and is not in this list, their login will be blocked.\n\n```\nGITHUB_ALLOWED_USERS=user1 user2 user3\n```\n\nTo set specific users as admins when they log in, define them in the config file:\n\n```\nGITHUB_ADMIN_USERS=user1 user2\n```\n\n\n#### Heroku Authentication\n\nYou can use Heroku's OAuth to log in to this site. This is intended to be used to quickstart the Heroku deploy button, and is really only meant to be used when a single user will be logging in, since it's somewhat difficult to configure after the initial setup.\n\nIf you are using the Heroku deploy button then this will all be configured automatically. If you'd like to set it up manually, the instructions are below.\n\nYou'll need to create a Heroku OAuth app, which you can do [from the command line](https://devcenter.heroku.com/articles/platform-api-reference#oauth-client-create). Set the redirect URL to `https://events.example.org/auth/heroku`. You'll need the client ID and secret that are provided after creating the app.\n\n```\nAUTH_METHOD=heroku\nHEROKU_CLIENT_ID=\nHEROKU_CLIENT_SECRET=\n```\n\nThere are no other config options to set permissions. The first user to log in will be the site admin. No other users will be able to log in after that. If you'd like, you can manually add Heroku user IDs to the database if you really do want other Heroku users to log in.\n\n\n#### OpenID Connect\n\nYou can configure Meetable to authenticate users via an OpenID Connect server. This is useful if you are already using a service like Auth0 or Okta and want to add this as another app for your organization.\n\nYou'll need to register an application at your OpenID Connect service and configure the redirect URL appropriately. You can also configure IdP-initiated login in order to let your users log in to Meetable from their dashboard at the OpenID Connect server. The templates for each URL are below:\n\n* Redirect URI: `https://events.example.org/auth/oidc`\n* Initiate Login URI: `https://events.example.org/auth/oidc/initiate`\n\nYou will also need to add the following configuration to Meetable:\n\n```\nOIDC_AUTHORIZATION_ENDPOINT=https://authorization-server.com/authorize\nOIDC_TOKEN_ENDPOINT=https://authorization-server.com/token\nOIDC_CLIENT_ID=\nOIDC_CLIENT_SECRET=\n```\n\nBy default, all users that exist at this server will be allowed to log in to Meetable. To limit who can log in, you can of course create policies at your OpenID Connect server to prevent users from being able to log in. If that's not an option, you can hard-code a list of user IDs who are allowed to log in here. Enter a space-separated string of each user's `sub` ID in the config:\n\n```\nOIDC_ALLOWED_USERS=sub1 sub2 sub3\n```\n\nTo set specific users as admins when they log in, define their `sub` IDs in the config file:\n\n```\nOIDC_ADMIN_USERS=sub1 sub2\n```\n\n\n#### Vouch Proxy\n\nIn this configuration, this project provides no authentication mechanism itself. Instead, it relies on the web server being able to authenticate users somehow, and setting an environment variable when users are logged in.\n\nWhen the `Remote-User` header is present, this app considers users logged-in with the value of that header as their unique user ID, which is expected to be a URL. As long as the app sees a `Remote-User` header, users will be considered logged in.\n\n[Vouch Proxy](https://github.com/vouch/vouch-proxy) can offload authentication to an external OAuth service, and can be configured to set the HTTP `Remote-User` header that this project looks for.\n\nConfigure the application to use Vouch and tell it the hostname of your Vouch server.\n\n```bash\nAUTH_METHOD=vouch\nVOUCH_HOSTNAME=sso.example.org\n```\n\nBelow is an example configuration for using Vouch proxy to set the `Remote-User` header.\n\nDeploy Vouch behind the hostname `sso.example.org`\n\n```\nserver {\n  listen 443 ssl http2;\n  server_name sso.example.org;\n\n  ssl_certificate /etc/letsencrypt/live/sso.example.org/fullchain.pem;\n  ssl_certificate_key /etc/letsencrypt/live/sso.example.org/privkey.pem;\n\n  access_log  /usr/local/nginx/logs/sso.access.log  main;\n  error_log  /usr/local/nginx/logs/sso.error.log;\n\n  location / {\n    proxy_set_header  Host  sso.example.org;\n    proxy_pass        http://127.0.0.1:9244;\n  }\n}\n```\n\nSee [Vouch examples](https://github.com/vouch/vouch-proxy/tree/master/config) for example configuration of the actual Vouch system.\n\nIn the `server` block for the events site, insert the following:\n\n```\n  auth_request /vouch-validate;\n  auth_request_set $auth_user $upstream_http_x_vouch_user;\n\n  location = /vouch-validate {\n    proxy_pass https://sso.example.org/validate;\n    proxy_pass_request_body     off;\n\n    proxy_set_header Content-Length \"\";\n    proxy_set_header X-Real-IP $remote_addr;\n    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    proxy_set_header X-Forwarded-Proto $scheme;\n\n    # these return values are fed to the @error401 call\n    auth_request_set $auth_resp_jwt $upstream_http_x_vouch_jwt;\n    auth_request_set $auth_resp_err $upstream_http_x_vouch_err;\n    auth_request_set $auth_resp_failcount $upstream_http_x_vouch_failcount;\n  }\n```\n\nIn the `location ~* \\.php` block which proxies requests to the PHP handler, add the following to turn the `$auth_user` variable set by Vouch into the `REMOTE_USER` setting read by PHP:\n\n```\n    fastcgi_param   REMOTE_USER $auth_user;\n    fastcgi_param   HTTP_REMOTE_USER $auth_user;\n```\n\nIf you want your website to be visible even to logged-out users, make sure Vouch is configured with `publicAccess: true` to avoid sending back an error page when users are not logged in.\n\nAll users created in this mode will be created as regular users. You'll need to manually configure specific accounts as admin accounts in the database after they log in.\n\n### Permissions\n\nPermissions in this site can be configured to support a few different use cases.\n\nYou can choose whether all users or just admin users can manage events and the website text.\n\n```\nALLOW_MANAGE_EVENTS=users\nALLOW_MANAGE_EVENTS=admins\nALLOW_MANAGE_SITE=users\nALLOW_MANAGE_SITE=admins\n```\n\nCurrently `ALLOW_MANAGE_EVENTS` enables access to everything around events, including creating, editing, and deleting events, as well as adding and deleting responses.\n\n\n## Installing on Heroku manually\n\n```\n# Make sure to set the organization if you're adding this to an account that is not your personal account\nexport HEROKU_ORGANIZATION=\n\ngit clone https://github.com/aaronpk/Meetable.git\n\ncd Meetable\n\nheroku git:remote -a your-heroku-app-name\n\n# Add MySQL\nheroku addons:create cleardb:ignite --as=DATABASE\n\n# Add CloudCube (AWS S3 storage)\nheroku addons:create cloudcube:free\n\n# Deploy the app to Heroku\ngit push heroku master\n\n# Visit the app in your browser and continue the setup there\n# Once you finish the setup walkthrough, it will give you a series of `heroku config:set` commands to run\n# Run all the provided `heroku config:set` commands...\n\nheroku config:set ...\n...\n```\n\n\n## License\n\nCopyright 2020-2023 by Aaron Parecki. Available under the MIT license.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faaronpk%2Fmeetable","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faaronpk%2Fmeetable","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faaronpk%2Fmeetable/lists"}