GithubHelp home page GithubHelp logo

southlondonmakerspace / membership-system Goto Github PK

View Code? Open in Web Editor NEW
44.0 11.0 19.0 2.21 MB

This is a membership management system, it's chiefly a database of member data for legal purposes, setting up subscription payments, managing access control permissions, logging events, and interfacing with Discourse permissions.

Home Page: http://southlondonmakerspace.org

License: Other

JavaScript 66.51% CSS 1.97% HTML 31.41% Dockerfile 0.12%
membership-management subscription payment membership makerspace hackspace

membership-system's People

Contributors

jclxx avatar mpress avatar naxxfish avatar pedrosland avatar petehellyer avatar thisislawatts avatar tomnewsom avatar unknowndomain 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

membership-system's Issues

Add support for payments other than regular recurring ones

Sometimes, we might want to record the fact a member has made a donation for some reason - for example they have donated for a specific purpose like time using a tool, or purchasing a material or component from the organisation.

At the moment payments are almost exclusively used for GoCardless recurring membership payments (Direct Debits). Ideally, the same database model should be used so that all payments are in the same format regardless of how they arrive, so should be flexible to include payments made via a PoS system, including card payments (chip+pin, contactless) and possibly cash payments.

Preferably, there should be a means for registering payments against a user through an API (e.g. to integrate with an ePoS system).

Wording in ”one time password" 2FA login screen

At the moment,where there is a 2nd factor Auth set up on your account, when you log in you get a prompt for a "one time password". Users don't always connect this with their 2FA method , and the TOTP code might not register as being a "password"

We should fix this page so this is more obvious

Lost Member Report

  • Name
  • Link to their profile
  • Email link
  • Date Registed
  • Date Mandate Died
  • Number of Mandates Paid
  • Door: Has permission / total opens / last opened
  • Shutter: Has permission / total operated / last operated
  • Other permissions count
  • Linked with discourse

Induction sessions functionality

User story: As a inductor (super user), I want to be able to schedule induction sessions, invite people who wish to take the induction, and easily tick off people who have attended an induction, and optionally grant a permission to attendees who have completed the session successfully.

As a member (user), I want to be able to sign up for induction sessions in order to get access to the tools I wish to use

There are several components to this:

  • Creating a type of induction (e.g. Laser Cutter, 3D Printer, Wood workshop), which (optionally) grants a permission on completion, possibly with prerequisite permissions (must have wood shop permission before being inducted on the lathe).
  • Scheduling sessions of a particular type of induction (at a given time, location, with a particular inductor)
  • Some method of potential inductees signing up to induction sessions (possibly through a waiting list mechanism)
  • Some way of an inductor recording the results of a session (e.g. that inductees have attended and successfully completed), and thus granting permissions as appropriate.

This functionality and workflow should map to the current induction signup process for SLMS, which is being recorded on the SLMS discourse here, but should be general and flexible enough that it can map to alternative workflows which may be use in other similar organisations.

src/js/template-locals.js contains database logic and probably shouldn't

/src/js/template-locals.js 's main purpose is to set global template variables for use in templates across all applications. Currently the file has a fair amount of overlap between the Controller/Model realm, and is applying logic to models rather than just representing them.

	if ( req.user &&
		 (	! req.user.emergency_contact.telephone ||
			! req.user.gocardless.mandate_id ||
			! req.user.gocardless.subscription_id ||
			! req.user.discourse.activated ||
			! req.user.discourse.username ||
			! req.user.tag.id
		) )
		res.locals.userSetup = false;

For example in this case, the "userSetup" field should probably really be added to the Member model as a virtual - such that the logic for determining if a user is set up or not is in the same place as other logic being applied about the Member.

This file generally could do with a review and refactoring.

create backlog

We need a (prioritised) list of what needs to be done so we aren't tripping over each other/ all working on the same problem.

Schema

One of the things we talked about last night was adjusting how the membership permissions are stored. At the moment they exist as:

var memberSchema = mongoose.Schema( {
  ...
  permissions: [ {
    permission: {
      type: ObjectId,
      ref: 'Permissions',
      required: true
    },
    date_added: {
      type: Date,
      default: Date.now,
      required: true
    },
    date_updated: {
      type: Date,
      default: Date.now,
      required: true
    },
    date_expires: {
      type: Date
    }
  } ]
} );

Put perhaps we need to reference another document. This would allow us to independently update the type of

var memberSchema = mongoose.Schema( {
  ...
  permissions: [ {
    type: ObjectId,
    ref: 'Access',
    required: true
  } ]
} );

var accessSchema = mongoose.Schema( {
  permission: {
    type: ObjectId,
    ref: 'Permissions',
    required: true
  },
  member: {
    type: ObjectId,
    ref: 'Members',
    required: true
  },
  date_added: {
    type: Date,
    default: Date.now,
    required: true
  },
  date_updated: {
    type: Date,
    default: Date.now,
    required: true
  },
  date_expires: {
    type: Date
  }
});

It was reading through this series 1, 2, 3, that got me thinking this might be a good way to go.

Having individual Access objects in this manner:

  • Allow us to quickly pull up everyone with DoorRights
  • Easy administration of individual access, ie. Luke's misplaced his keys, revoke all DoorRights

Aware that there will need to be some refactoring if we affect a schema change but I think it's worth taking the time on this foundation. Let me know your thoughts!

Discourse integration

(I'm not a coder, so excuse me if I say some stupid things here)

It would be very useful if the membership system could drive Discourse to automatically promote/demote people from user groups.

Payment collected = Promote to Member. Payment expire = Demote from Member
Laser Permission added = Promote to Laserer
Shutter access = Shutterer

etc.

This can be done entirely via the Discourse API. I've tested the following commands at the command line.

Get list of Groups

curl -X GET https://discourse.southlondonmakerspace.org/admin/groups.json

You want the "id" value. eg 41 for "members"

Get member info based on their email address

curl -X GET -d [email protected] -d api_username=ApiUsernameGoesHere -d api_key=ApiKeyGoesHere https://discourse.southlondonmakerspace.org/admin/users/list/active.json

Note that this will return all users whose email address partly matches the search, so will return [email protected] and [email protected] You need to do your own quick == comparison to make sure you get the right one.

You want the "username" value, eg. "tomnewsom" for this email address

Add member to group
(note that usernames= will accept a comma separated list)

curl -X PUT -d usernames=tomnewsom -d api_key=ApiKeyGoesHere -d api_username=ApiUsernameGoesHere https://discourse.southlondonmakerspace.org/admin/groups/41/members.json

Remove member from group
(note that this is a one-at-a-time operation)

curl -X DELETE -d username=username -d api_key=ApiKeyGoesHere -d api_username=ApiUsernameGoesHere https://discourse.southlondonmakerspace.org/admin/groups/41/members.json

Finally, if someone is joining SLMS and they don't have a Discourse account yet:

Create a new user

curl -X POST -d name=FullName -d username=UserName -d [email protected] -d password=Password -d active=true -d api_key=ApiKeyGoesHere -d api_username=ApiUsernameGoesHere https://discourse.southlondonmakerspace.org/users

I think if you leave active=false, then you can further prod the API to send an "activate this account" email, which is probably more secure.

Member Subscription Report

  • Name
  • Link to their profile
  • Email link
  • Their minimum subscription setting if not set to the default.
  • Subscription amount

Directory listing

It's a legal requirement for there to be a listing of every member with their contact details

TOTP issuing QR code does not have Issuer parameters

Currently the 2FA TOTP code generation doesn't include an issuer or system in the identity it encodes into the url.

Using key format scheme as a guide, the otpauth uri should contain an issuer based on organisation name option, and with a pre/suffix of DEV if we are in development mode.

Without this, if a user is using multiple instances of the membership system - scanning a QR code for one may overwrite the other, or they may become confused. This is particularly an issue for developers who will have their own instance as a live one potentially.

Permissions system should be more elegant

Right now, any place where permissions are involved in the application, many if statements sprout up.

The Member/Permission model does not have a convienient way to assess whether a user has a particular permission or not. Edge cases like super-admins (who should be permitted all permissions) are handled multiple times throughout the code.

We should put this common function somewhere where it can be reused, and applied consistently.

Improvements to discourse-find

If we can't find a discourse user that matches, offer two options:

  1. enter a discourse username or email
  2. create a new user (using membership Name as discourse username and realname)

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.