Giter VIP home page Giter VIP logo

meetable's Introduction

Meetable

Deploy

Meetable is a minimal events aggregator website.

You can see a live version of this project at:

Features

  • Discovery List of upcoming events on the home page, and archive view of past events.
  • Tags Events can have one or more tags. Commonly-used tags are shown on the home page as well as the "discover" page.
  • 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.
  • Add to Calendar Events have an "Add to Calendar" link that exports either an iCal file or links to Google Calendar.

Event Pages

Events have a permalink that contains

  • cover photo
  • event name, date/time and location details
  • a link to an external website and ticket URL
  • a description of the event, which supports markdown and basic HTML formatting
  • a link to a timezone converter
  • RSVPs (an RSVP button appears for logged-in users)
  • photos, blog posts, and notes about the event

When logged in, you can add photos directly to an event page. Event pages also accept webmentions so that people can add photos and notes to the page from their own websites.

Setup

Requirements

  • PHP 8.2+
  • Composer
  • MySQL/MariaDB
  • Optional: Redis

Installation

This project is based on Laravel, so you can defer to their instructions if you encounter any issues.

Clone the source into a folder

git clone https://github.com/aaronpk/Meetable.git
cd Meetable

Install the project's dependencies

composer install

Make sure the storage folder is writable by the web server

sudo chown -R www-data: storage

Copy .env.example to .env and fill it out following the instructions in the file

cp .env.example .env

Once you've configured everything in the .env file, you can run the migrations to set up the database

php artisan migrate

In a production system you'll want to make sure the background worker script is running:

php artisan queue:listen

Alternatively, you can set up a cron job to run every minute which will process any jobs on the queue:

php artisan queue:work --stop-when-empty

Web Server

Configure your web server to serve the project's public folder from the domain name you've set up.

For nginx:

server {
  listen 443 ssl http2;
  server_name  events.example.org;

  ssl_certificate /etc/letsencrypt/live/events.example.org/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/events.example.org/privkey.pem;

  root /web/sites/events.example.org/public;

  index index.php;
  try_files $uri /index.php?$args;

  location ~* \.php$ {
    fastcgi_pass    php-pool;
    fastcgi_index   index.php;
    fastcgi_split_path_info ^(.+\.php)(.*)$;
    include fastcgi_params;
    fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
  }
}

If you're using the local storage driver to store uploaded images on disk, then make sure to symlink the storage folder:

php artisan storage:link

Authentication

There 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.

In your configuration file, you'll need to tell the project which authentication method to use:

AUTH_METHOD=

Provide one of the supported values for AUTH_METHOD:

  • session (passkey login)
  • github
  • oidc
  • vouch
  • heroku

You 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.

AUTH_SHOW_LOGIN=true
AUTH_SHOW_LOGOUT=false

Passkey Authentication

If 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.

After 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.

This 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.

If you expect multiple users to log in to manage the content, use one of the multi-user options below.

GitHub Authentication

With 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.

You'll need to create a GitHub OAuth application 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.

AUTH_METHOD=github
GITHUB_CLIENT_ID=
GITHUB_CLIENT_SECRET=

If 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.

GITHUB_ALLOWED_USERS=user1 user2 user3

To set specific users as admins when they log in, define them in the config file:

GITHUB_ADMIN_USERS=user1 user2

Heroku Authentication

You 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.

If 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.

You'll need to create a Heroku OAuth app, which you can do from the command line. 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.

AUTH_METHOD=heroku
HEROKU_CLIENT_ID=
HEROKU_CLIENT_SECRET=

There 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.

OpenID Connect

You 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.

You'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:

  • Redirect URI: https://events.example.org/auth/oidc
  • Initiate Login URI: https://events.example.org/auth/oidc/initiate

You will also need to add the following configuration to Meetable:

OIDC_AUTHORIZATION_ENDPOINT=https://authorization-server.com/authorize
OIDC_TOKEN_ENDPOINT=https://authorization-server.com/token
OIDC_CLIENT_ID=
OIDC_CLIENT_SECRET=

By 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:

OIDC_ALLOWED_USERS=sub1 sub2 sub3

To set specific users as admins when they log in, define their sub IDs in the config file:

OIDC_ADMIN_USERS=sub1 sub2

Vouch Proxy

In 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.

When 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.

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.

Configure the application to use Vouch and tell it the hostname of your Vouch server.

AUTH_METHOD=vouch
VOUCH_HOSTNAME=sso.example.org

Below is an example configuration for using Vouch proxy to set the Remote-User header.

Deploy Vouch behind the hostname sso.example.org

server {
  listen 443 ssl http2;
  server_name sso.example.org;

  ssl_certificate /etc/letsencrypt/live/sso.example.org/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/sso.example.org/privkey.pem;

  access_log  /usr/local/nginx/logs/sso.access.log  main;
  error_log  /usr/local/nginx/logs/sso.error.log;

  location / {
    proxy_set_header  Host  sso.example.org;
    proxy_pass        http://127.0.0.1:9244;
  }
}

See Vouch examples for example configuration of the actual Vouch system.

In the server block for the events site, insert the following:

  auth_request /vouch-validate;
  auth_request_set $auth_user $upstream_http_x_vouch_user;

  location = /vouch-validate {
    proxy_pass https://sso.example.org/validate;
    proxy_pass_request_body     off;

    proxy_set_header Content-Length "";
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;

    # these return values are fed to the @error401 call
    auth_request_set $auth_resp_jwt $upstream_http_x_vouch_jwt;
    auth_request_set $auth_resp_err $upstream_http_x_vouch_err;
    auth_request_set $auth_resp_failcount $upstream_http_x_vouch_failcount;
  }

In 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:

    fastcgi_param   REMOTE_USER $auth_user;
    fastcgi_param   HTTP_REMOTE_USER $auth_user;

If 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.

All 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.

Permissions

Permissions in this site can be configured to support a few different use cases.

You can choose whether all users or just admin users can manage events and the website text.

ALLOW_MANAGE_EVENTS=users
ALLOW_MANAGE_EVENTS=admins
ALLOW_MANAGE_SITE=users
ALLOW_MANAGE_SITE=admins

Currently ALLOW_MANAGE_EVENTS enables access to everything around events, including creating, editing, and deleting events, as well as adding and deleting responses.

Installing on Heroku manually

# Make sure to set the organization if you're adding this to an account that is not your personal account
export HEROKU_ORGANIZATION=

git clone https://github.com/aaronpk/Meetable.git

cd Meetable

heroku git:remote -a your-heroku-app-name

# Add MySQL
heroku addons:create cleardb:ignite --as=DATABASE

# Add CloudCube (AWS S3 storage)
heroku addons:create cloudcube:free

# Deploy the app to Heroku
git push heroku master

# Visit the app in your browser and continue the setup there
# Once you finish the setup walkthrough, it will give you a series of `heroku config:set` commands to run
# Run all the provided `heroku config:set` commands...

heroku config:set ...
...

License

Copyright 2020-2023 by Aaron Parecki. Available under the MIT license.

meetable's People

Contributors

aaronpk avatar capjamesg avatar dependabot[bot] avatar gregorlove avatar lewiscowles1986 avatar sknebel avatar zegnat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

meetable's Issues

Import event from a URL

Should provide a UI to enter an event URL to import from:

  • h-event
  • hEvent
  • ics
  • Eventbrite
  • Meetup

add "ticket URL" field to events

if a ticket URL is set on an event, then disable RSVPs.

add a new column "rsvps_enabled" which is set automatically based on the presence of the ticket URL field.

Update URL handling to route even with missing unique ID

Since it's rare that an event slug will collide with another during the same month, it should be possible to link to events using an even shorter URL than the one that includes the unique ID at the end.

For an event like /2020/01/a-b-c-uniqueID, the URL /2020/01/a should redirect to the canonical URL. If there are more than one event possibilities for the given slug prefix then show all matching events. This ensures previously redirecting URLs will still show the correct event if a conflicting URL is added later.

Add configurable text blocks in various places

Admins of the website need a way to add their own text to various parts of the website. Things like notices on the "Add an Event" page to provide a short sentence describing what events are useful/relevant to this website.

Maybe every page can have an editable text block at the top.

  • home page
  • add an event (would this also appear while editing?)
  • tag pages
  • past events
  • year and month permalinks
  • edit responses
  • add a photo

Delete blog post

Provide a UI to delete blog post responses.

For blog posts sent via webmention, prevent the same URL from being shown again if a future webmention is sent.

Add timezone support

  • When a location is set, also set the timezone based on the location
  • Events with no times do not show timezone info anywhere including the ical feed
  • Events with a start/end time render floating time if no timezone is set, and output timezone info in the ical feed if present

Create backup/export command

Create a command that exports all events and responses as files on disk that can be added to a git repository.

Probably some sort of folder structure like:

  • YYYY/mm/ID/event.json - the event details
  • YYYY/mm/ID/photos/0000000.jpg - photos
  • YYYY/mm/ID/responses/000000.json responses

Make sure to remove files from the folder if the event or response have been deleted.

Featured photos

Events should support a featured image

  • must be able to set the featured image when creating an event
  • cloning a previous event will copy the featured image as well

Drop dependency on go imageproxy

While the go imageproxy this uses is fantastic, it's not reasonable to expect others to configure that alongside this project. We are not proxying arbitrary URLs here since everything gets downloaded anyway, so it should be possible to store resized versions of all the image locally and serve those directly.

Create some sort of theming/styling mechanism

The current design of this website is intentionally minimal. It is meant to be able to be themed or styled to match a particular brand later.

The software will need to add some sort of support for theming in order to allow this easily. The challenge will be doing it in a way that doesn't require creating full WordPress-like themes, but I am not sure exactly what form this should take yet either.

If the theming support includes being able to change the HTML, then we'll need to add a test suite that checks the Microformats on event pages so people can make sure they aren't messing up the microformats when creating themes.

Alternatively, theming could be only allowed via CSS.

Add options for authentication

Currently the only authentication mechanism is reading the Remote-User HTTP header. In order to be easier to install, the website should provide other options for authentication. Some options:

  • local user accounts with email/password
  • email magic link
  • configurable OAuth provider (e.g. log in with GitHub, Google, Twitter, IndieAuth, etc)

Some open questions:

  • Should an instance be able to support multiple providers (e.g. GitHub and Twitter) and if so, how to deal with duplicate/merging accounts?
  • Some instances may want to limit editing capability even for logged-in users, so there may need to be added a permissions system so that only certain users can do things like edit events or moderate responses

Import photo from a URL

Support both h-entry as well as direct image URLs. Provide a way to add alt text if there is none found.

API to add a response

For a Loqi hook to quickly add a photo or blog post to an event.

Should immediately add the response with whatever it was able to find.

Import a blog post from a URL

Provide a UI to import a blog post from a URL. Expect h-entry and preview before adding. Provide a way to override the name from what was found at the h-entry.

Edit photos and alt text

Provide a UI to edit existing photos and their alt text. If the photo was from an external URL, show that it has been edited.

Create web installer

I'd like to provide a web installer for people so the experience of setting this up is more like WordPress. Once you download the files onto your server, the installer should walk through the processing of checking system requirements, setting up the database, collecting config info, etc.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.