jkuester:altcha

v1.0.1Published 4 weeks ago

Meteor Altcha

Project Status: Active – The project has reached a stable, usable state and is being actively developed. Test suite

Easy Meteor integration for Altcha. Works with any frontend.

Table of Contents generated with DocToc

Installation

First, add this package via meteor add jkuester:altcha Then install the Altcha client input type via npm install --save altcha.

Settings setup

For increased security, the internals are configured via Meteor.settings. If you haven't created a Meteor settings file then you can do it via

echo "{}" > settings.json

So you can start your Meteor app using the settings via meteor --settings=settings.json.

An example settings for altha may look like he following:

1{
2  "public": {
3    "altcha": {
4      "challengeUrl": "/altcha-challenge"
5    }
6  },
7  "altcha": {
8    "algorithm": "SHA-256",
9    "challengeUrl": "/altcha-challenge",
10    "hmacKey": "01234567890abcdefghijklmnopqrstuvwxyz",
11    "maxNumber": 1000000,
12    "expirationAfter": 300000
13  }
14}

The public part is only needed if you want to configure the challenge url via settings.

Server setup

Now you need to initialize it on the server. You can optionally pass a Mongo.Collection as storage for solved challenges (prevent Replay Attacks) or a name of the collection or omit to use an in-memory collection:

1import { Meteor } from 'meteor/meteor';
2import * as Altcha from 'meteor/jkuester:altcha';
3
4Meteor.startup(() => {
5  Altcha.init()
6});

As you can see there is an optional debug param, which you can pass a function to, so the internal is passed to it. Beware to disable it in production, though.

Client Setup

On your client you can simply follow the altcha integration guide.

The most minimal setup is to use the altcha component and only configure the challenge-url. The following is a Blaze example, but you are free to use any frontend!

<template name="myForm">
    <form id="myForm">
        <input type="text" name="username" placeholder="Username" />
        <altcha-widget challengeurl="{{settings.altcha.challengeUrl}}" debug></altcha-widget>
        <button type="submit">Submit</button>
    </form>
</template>
1import { Template } from 'meteor/templating';
2import './myForm.html';
3import 'altcha'; // this is the npm package, not the Meteor package!
4
5Template.registerHelper('settings', () => Meteor.settings.public)
6
7Template.myForm.events({
8  'submit #myForm' (event) {
9    event.preventDefault()
10
11    const data = Object.fromEntries(new FormData(event.target).entries())
12
13    // see next section
14    Meteor.call('validateForm', data, (err, res) => {
15      if (err) {
16        alert(err.message)
17      }
18      else {
19        event.target.reset()
20      }
21    })
22  },
23});

Service Worker considerations

If you're using a service worker then you should make sure, it ignores the challenge url.

Otherwise, aggressive caching might cause forms to reuse existing challenges which in turn are rejected by default when validating.

Form submission and validation

In the above example we now validate the submitted form by sending the data to a Meteor Method endpoint.

For the above example, the endpoint simply looks like this:

1Meteor.methods({
2  async validateForm ({ username, altcha }) {
3    const isValid = await Altcha.validate(altcha);
4    if (!isValid) {
5      throw new Meteor.Error(403, 'challenge failed')
6    }
7    // challenge passed, you can
8    // continue with the form submission
9    // data processing
10  }
11})

The default field name for the altcha is altcha and you should consider this in your schema, if you do Methods- validation using a schema, like SimpleSchema, zod, etc.

API Documentation

The API is documented in a separate API.md file.

Contribution

Thank you for considering to contribute! To make both our time worth the effort, please get familiar with the contribution guide, the security guide and the code of conduct.

License

MIT, see license file.