GithubHelp home page GithubHelp logo

zalando-incubator / authmosphere Goto Github PK

View Code? Open in Web Editor NEW
54.0 8.0 12.0 1.61 MB

A library to support OAuth2 workflows in JavaScript projects

License: MIT License

TypeScript 93.74% JavaScript 6.26%
oauth2 express-middleware typescript authentication

authmosphere's Introduction

authmosphere {๐ŸŒ}

Build Status npm download npm version

Introduction

{authmosphere} is a library to support and test OAuth 2.0 workflows in JavaScript projects.

It's implemented in TypeScript which improves the development experience via implicit documentation with types and first-class IDE support. The library itself is transpiled to JavaScript (ES6) so there is no need for a TypeScript compiler to use authmosphere in JavaScript projects.

The following OAuth flows are supported:

The Authmosphere JavaScript API supports:

Usage

For a comprehensive documentation checkout out the API documentation.

Request and cache tokens

import { TokenCache, OAuthGrantType } from 'authmosphere';

const oAuthConfig = {
  grantType: OAuthGrantType.CLIENT_CREDENTIALS_GRANT,
  accessTokenEndpoint: 'https://example.com/access_token',
  credentialsDir: './credentialsDir'
};

const tokenConfig = {
  'service-foo': ['foo.read', 'foo.write'],
  'service-bar': ['bar.read']
};

// create a new TokenCache instance
const tokenCache = new TokenCache(tokenConfig, oAuthConfig);

// request and resolve a token from the cache
tokenCache
  .get('service-foo') // needs to match with a key from 'tokenConfig'
  .then((token) => { /* ...use the token... */ });

Secure express endpoints

import { authenticationMiddleware, requireScopesMiddleware } from 'authmosphere';

// extract and validate access token (authorization header)
// and reject requests without valid access token
app.use(authenticationMiddleware({ tokenInfoEndpoint: 'https://example.com/token_validation' });

// only allow access for requests with tokens that have scopeA and scopeB
app.get('/secured/route', requireScopesMiddleware(['scopeA', 'scopeB']), (request, response) => {
  // handle request
});

Setup

  • node >= 6.0.0 required to consume this library
  • npm install authmosphere

OAuth documentation

Changelog and Migration

Development

  • clone this repo
  • npm install
  • to build: npm run build
  • to lint: npm run lint

Testing

  • npm test - runs all tests
  • npm run unit-test - runs unit tests
  • npm run integration-test - runs integration tests

License

MIT License (MIT)

Copyright (c) 2021 Zalando SE

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

authmosphere's People

Contributors

alftron avatar awaltert avatar bezrodnov avatar bzums avatar dependabot[bot] avatar fokusferit avatar hypescript avatar iso50 avatar jans510 avatar m-achatz avatar retro64 avatar shuhei avatar valentinfunk 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

authmosphere's Issues

Provide helper function to obtain acccess_token

We consume different services and access_tokens via the 'tokenCache' implementation.
Therefore we used this construct in different places and several times:

function getAccessToken() {
  return tokenCache.get("specific_key")
                .then(tokeninfo => tokeninfo.access_token);
}

Our solution is to provide a factory which can be consumed to access a specific key:

function accessTokenFactory(key: string): () => Promise<string> {
   return function () { 
      return tokenCache
               .get(key)
               .then(tokenInfo => tokenInfo.access_token);
  };
}

Maybe this function could be handy in the library as well ๐Ÿ˜„

Enhance type information for token type

The indexer defined on the token type currently lacks type information, as in #81 the return type was explicitly set to any.

In sum, there are two problems present with the current solution:

  • The indexer doesn't describe the current shape of the token object
  • Types can work as documentation in the case of the indexer
  • If the structure changes, it would be also maintainable due to the use of union types.

Improve types and export relevant ones

For example the Token type can be improved, instead of:

interface Token {
  access_token: string;
  expires_in: number;
  scope: string;
  token_type: string;
}

we should use something like:

interface Token {
  access_token: string
  expires_in?: number
  scope?: string
  token_type?: string
  [key: string]: {}
}

since we do not know what properties are exactly set on the tokens in different implementations. Furthermore, the Token type should be exported by the library. For the typesToken and Tokeninfo we should check again whether it is necessary to have two types or if one (which is than more generic) is enough.

Use a percentage-based strategy to refresh cached tokens

In the TokenCache we currently refresh tokens based on a hardcoded threshold: https://github.com/zalando-incubator/lib-oauth-tooling/blob/master/src/TokenCache.ts#L8, used in https://github.com/zalando-incubator/lib-oauth-tooling/blob/master/src/TokenCache.ts#L96

To be more resilient we should refresh tokens based on the percentage of their lifetime, for example when 50% of the expiration time is met. We should default this value to 50% and provide an option to be able to parameterise this value.

Fix linting

Linting is currently not working correctly due to wrong glob expandation.

Cleanup

Do some cleanup and increase code coverage

Rename project

  • Find name (auth-mosphere)
  • Update readme
  • Update packages.json
  • push new version
  • Restart versioning at 1.0.0 #92

Remove Zalando dependency `REALM`

Currently, this lib can only be used with the Zalando OAuth server since a REALM is accepted in the OAuth config (used in https://github.com/zalando-incubator/lib-oauth-tooling/blob/d222a021d20b2440d3662f0249dd1057fb50c23e/src/oauth-tooling.ts#L155 and https://github.com/zalando-incubator/lib-oauth-tooling/blob/d222a021d20b2440d3662f0249dd1057fb50c23e/src/TokenCache.ts#L44).

It should be removed from the config. For Zalando internal use one should use the queryParameter option proposed in #39

Provide possibility to add arbitrary query parameters to token request

Currently, there is no way to add query parameters to a server request.
However, there are multiple use-cases:

Therefore, the OAuth config object (used in https://github.com/zalando-incubator/lib-oauth-tooling/blob/d222a021d20b2440d3662f0249dd1057fb50c23e/src/oauth-tooling.ts#L155) should be extended by an property queryParameters which accepts a HashMap of key value pairs which will be added to server requests.

Improve/extend Documentation

Decide on what type of documentation do we want to use:

  • are we fine with the readme and api doc as is?
  • do we want to provide additional diagrams/code examples to also explain OAuth 2.0 to a certain degree to really make it easy for the developer to use this lib

Add publishConfig to package.json

Add

  "publishConfig": {
    "registry": "https://registry.npmjs.org/"
  },

to package.json to make sure that the public registry is used when publishing the package.

Support explicitly passing credentials in OAuthConfig

Currently you can only pass (user or client) credentials implicitly via the credentialsDir option in the OAuthConfig type. However it may be necessary sometimes to pass such information explicitly via a string. Furthermore, not for all grant types both information are mandatory.

This ticket may be related to #110 depending on the concrete solution.

See the current validation of OAuthConfig: https://github.com/zalando-incubator/authmosphere/blob/master/src/oauth-tooling.ts#L185 resp. https://github.com/zalando-incubator/authmosphere/blob/master/src/utils.ts#L143
See the current solution of reading in the credentials: https://github.com/zalando-incubator/authmosphere/blob/master/src/oauth-tooling.ts#L187

Improve documentation on OAuth configuration

In the documentation under oauthConfig, the config values should be entered using strings, for example 'PASSWORD_CREDENTIALS_GRANT' for grant type. Expected from the lib are not strings but constants, like PASSWORD_CREDENTIALS_GRANT = 'password'. So in order to enter a working configuration, the constant have to be entered, or a 'password' string. There should be a description on how to import and use the constants.

Expose more explicit error messages / fail early

For example, if authorization header is not set we do not even have to try to call an endpoint, instead fail early (see oauth-tooling.ts).

Furthermore, validation of config in getAccessToken should not just throw but reject the returned promise (see oauth-tooling.ts).

[requireScopesMiddleware] is lacking error handling

https://github.com/zalando-incubator/lib-oauth-tooling/blob/master/src/express-tooling.ts#L40

precedenceFunction(req, res, next)
.then(result => {
  if (result) {
    next();
  } else {
     validateScopes(req, res, next, scopes);
  }
});

If precendenceFunction throws an error this is not handled well.
There should be an catch clause that executes and error handler that is passed by from the calling function.
This handler would allow the application to answer with an 500 or 403 or whatever is intended.

I suggest to change the API:

interface IPrecedenceFunction {
  (req: any, res: any, next: Function): Promise<boolean>;
}

interface IPrecedenceOptions {
  precedenceFunction: IPrecedenceFunction,
  precedenceErrorHandler: Function
}

function requireScopesMiddleware(scopes: string[],
                                 precedenceOptions?: IPrecedenceOptions) {

Fix Token type

Use

interface Token {
  access_token: string;
  expires_in?: number;
  scope?: string[];
  token_type?: string;
  local_expiry?: number;
  [key: string]: any; // <= instead of[key: string]: {};
}

to fix type errors with strict typescript configurations.

Make require scopes more flexible

Something like

requireScopesMiddleware(scopes: string[], precedenceFunction:Function) {

where precedenceFunction when returning true will overwrite the normal scope check.
--> This would allow to check for optional scopes that are only allowed when another conidition is met.

TODO

  • improve requireScopesMiddleware
  • move express related stuff into a seperate file
    • move tests to a separate file

PR will follow.

Update dependencies

For example update node-uuid to uuid to get rid of warning on npm install

Provide valuable type information

Type definitions serve multiple purposes. One one side, they help the compiler to determine choices depending of context and enrich the development workflow.
On the other side, do they provide documentation for possible consumers and readers.

In terms of #15 and #30, I would like to suggest to enrich the project with valuable type information to promote the usage of this library.

Add missing meta info files

  1. For better support of internal open source tooling, we should have a file containing the maintainers. (DONE in #68)
  2. CatWatch. Is this also need for incubator projects?
  3. More stuff we could takle with this issue?
  4. Contributing.md see #20

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.