sjudson / paseto.js

PASETO: Platform-Agnostic Security Tokens
MIT License
271 stars 16 forks source link

Basic high level API functionality #17

Closed stefanvanherwijnen closed 9 months ago

stefanvanherwijnen commented 5 years ago

I added some basic high level API functionality similar to https://github.com/paragonie/paseto . Could you provide some feedback and let me know if I am on the right track? With this, the creation of a token is possible with Paseto.Builder().setKey(key).setClaims(claims).toString()

Obviously a lot is missing compared to the reference implementation, but I'd like to know if what I am doing is any useful before I continue.

sjudson commented 5 years ago

Agreed with @PCouaillier --- further, I'd like any such PR to follow the code style of the remainder of the library, e.g., using the prototype idiom for class definitions as opposed to the explicit class keyword.

PCouaillier commented 5 years ago

@sjudson I have created a small npm package for my needs some weeks ago (pasetohlvl)...

import { addInstanceFactory, Duration, getInstance, MessageFactory } from 'pasetohlvl';

const KnownLocalKey = Buffer.from('DL/1XkMvU6Qw8OXgA430Fm4BdkCmyjnlG+NsZvM5VCc=', 'base64');
const knownPrivateKey = Buffer.from('2lR/xbDCIT1CHec7zz96//iyxQ4xv+MYBtrOVV11k6gPo8OLG1+o+07E+ZwIBI72wA4DD7A+7GwebzCL0fwWkw==', 'base64');

addInstanceFactory('local', async (factory) => ({
    local: await factory.getLocalKey(),
    private: await factory.getPrivateKey(knownPrivateKey),
}));

addInstanceFactory('private', async (factory) => ({
    private: await factory.getPrivateKey(),
}));

const durationOfFiveMinutes = Duration.shortDuration(5);
const durationOfTwoYearOneMounth = new Duration(2, 1);

const longLivingMessageFactory = new MessageFactory({ duration: durationOfTwoYearOneMounth });
const shortLivingMessageFactory = new MessageFactory({ duration: durationOfFiveMinutes });

const validatorFactory = new ValidatorFactory({issuer: 'paragonie.com'})

async function useInstances () {
    const { local } = await getInstance('local');
    const { private, public} = await getInstance('private');
    const longTimeCryptedMessage = await local.encrypt(longLivingMessageFactory.createMessage({hello: 'world'}));
    const message = await local.decrypt(longTimeCryptedMessage );
    const messageValidator = validatorFactory.validator(message);
    // assert.ok(messageValidator.isValid({ OR
    assert.ok(!messageValidator.isValidStrict({
        audience: 'pie-hosted.com';
        tokenIdentifier: '87IFSGFgPNtQNNuw0AtuLttPYFfYwOkjhqdWcLoYQHvL';
        issuer: 'paragonie.com';
        subject: 'documentation'
    }));
}

If you wan't I can translate it to javascript and submit a PR.

stefanvanherwijnen commented 5 years ago

@sjudson Alright, thanks. I will update it and try to follow the code style. I understand that the changes currently are too light, but you have to start somewhere. And instead of everyone trying to implement it in their own way, we might as well collaborate and try to create some high-level API functionality.

Is there also an RFC for the high-level API? Correct me if I'm wrong, but it looks like the RFC only describes the already implemented low-level API?

PCouaillier commented 5 years ago

The only things I've seen is : https://github.com/paragonie/paseto/tree/master/docs/03-Implementation-Guide

stefanvanherwijnen commented 5 years ago

I added some V2 functionality and tests for creating and parsing the token. @PCouaillier I think it would be nice if you could integrate your package's functionality into this PR (or a new PR, just hoping we can implement a proper high-level API. Whatever the case, I'm willing to help).

sjudson commented 5 years ago

When tests are passing I'll give this a proper look over.

stefanvanherwijnen commented 5 years ago

I didn't realize the tests were broken. Fixed them now and added issuedBy functionality.

stefanvanherwijnen commented 5 years ago

@sjudson When I run the tests locally, they all pass. However Travis generates the error: TypeError: Raw key must be provided as a buffer Any clue on how to fix this?

PCouaillier commented 5 years ago

From the source of sodium I can that the function you call return :

"outputs": [
                {
                        "type": "buf",
                        "name": "publicKey",
                        "length": "libsodium._crypto_sign_publickeybytes()"
                },
                {
                        "type": "buf",
                        "name": "privateKey",
                        "length": "libsodium._crypto_sign_secretkeybytes()"
                }
]

In the output of lib wrapper (dist folder) I can see that it uses Uint8Array maybe. Maybe the solution bellow will solve this issue...

Buffer.from(publicKey, 'binary')
stefanvanherwijnen commented 5 years ago

The tests in V2.test.js use the same approach however and they do not result in an error. So either I am making some dumb mistake, or something is messed up somewhere deeper in libsodium perhaps.

PCouaillier commented 5 years ago

I'll try tomorow with some docker containers to reproduce the bug.

PCouaillier commented 5 years ago

Work with :

I don't have any solution...

sjudson commented 5 years ago

I should have some time in the next week or so to pull the branch and take a look myself.

stefanvanherwijnen commented 5 years ago

I managed to fix the test with help of: https://github.com/sjudson/paseto.js/commit/265f042f0c71c14a699ed0a415966767b4e39d4b

However, node 6 fails because async functions are not supported.

Edit: more problems with node 6 apparently. Does Node 6 have to be supported?

sjudson commented 5 years ago

No. It's unlikely this will end up in a release before the end of the month, when Node 6 support drops. So you can drop it from the travis config if you'd like.

stefanvanherwijnen commented 5 years ago

Ok, thanks. Tests are finally passing now. Please let me know what the required changes are to the code and I will (try to) fix it.

stefanvanherwijnen commented 5 years ago

Any news on this?

sjudson commented 5 years ago

Been short of time as of late, not sure when I'll have an opportunity to review, but hopefully soon.