0.14.7 • Published 4 years ago

@rocketbase/skeleton-key v0.14.7

Weekly downloads
125
License
MIT
Repository
github
Last release
4 years ago

skeleton-key

Maintainability Test Coverage Build Status npm (scoped) NPM

A Client-Side JS Authentication and Authorization Library for Commons Auth

Install

npm i @rocketbase/skeleton-key

Examples

// auth.ts
import {SkeletonKey} from "@rocketbase/skeleton-key";
export const auth = new SkeletonKey();

// api.ts
import {auth} from "./auth";
import axios from "axios";

export async function getData() {
  if (!auth.isLoggedIn())
    throw new Error("Need to be logged in!");
  // Auth headers are appended automatically.
  return axios.get('/the/data');
}

export async function getOtherData() {
  // Auth headers are not appended unless this app is hosted on example.com
  return axios.get('https://example.com/other/data');
}

export function getUserId() {
  // Data encoded in the jwt is accessible through tokenData and refreshTokenData getter.
  return auth.tokenData.payload.customerId;
}

export function getUserAttributes() {
  // Data returned as the user response is accessible through the userData getter.
  return auth.userData;
}
// auth.ts
import {SkeletonKey} from "@rocketbase/skeleton-key";

interface UserExtensions {
  customAttributes: string;
  goHere: boolean;
  forTypingAssist: any[]
}

interface JwtExtensions {
  tokenExtensions: string;
  goHere: number;
  forTypingAssist: any
}

export const auth = new SkeletonKey<UserExtensions, JwtExtensions>({
  domains: ['*'],                           // Will insert auth headers for every domain
  url: "https://the.auth.server/path",      // Path to the auth server to run requests against
  intercept: true,                          // Automatically intercept all requests and insert headers where necessary
  renewType: "action",                      // Automatically refresh token once it expires
  authHeader: "Authorization",              // The header to inject the token under
  authPrefix: "Bearer ",                    // Prefix of the header value
  authSuffix: "",                           // Suffix of the header value
  storageKey: "io.rocketbase.commons.auth"  // The key in localStorage the token and user data is persisted under
});

// decorators.ts
import {auth} from "./auth";
import {LoginDialog} from "./some/LoginDialog";

/**
 * Checks if a user is logged in.
 * If not, delays execution until successful login and trigger a login dialog
 */
export function NeedsLogin(target: any, propertyKey: string | symbol, desc: PropertyDescriptor) {
  const {value} = desc;
  desc.value = async function(this: any, ...args: any[]) {
    if (!auth.isLoggedIn()) {
      LoginDialog.open();
      await auth.waitForLogin();
    }
    return value.apply(this, args);
  };
  return desc;
}

/**
 * Checks if a user has a given role.
 * If not, prevents execution and throws an error.
 */
export function NeedsRole(role: string) {
  return function(target: any, propertyKey: string | symbol, desc: PropertyDescriptor) {
    const {value} = desc;
    desc.value = function(this: any, ...args: any[]) {
      if (!auth.isLoggedIn() || !auth.userData.roles.contains(role))
        throw new Error(`User needs to be member of role ${role}!`);
      return value.apply(this, args);
    }
    return desc;
  }
}

// api.ts
import {NeedsLogin, NeedsRole} from "./decorators";
import axios from "axios";

export class Api {
  
  @NeedsLogin
  async getSomeData(id: string) {
    return axios.get(`/path/to/service/data/${id}`);
  }
  
  @NeedsRole("ADMIN")
  async getUserData(id: string) {
    return axios.get(`/path/to/service/users/${id}`);
  }
  
  // Can also be combined
  @NeedsLogin
  @NeedsRole("ADMIN")
  async setUserPassword(id: string, password: string) {
    return axios.put(`/path/to/service/users/${id}`, JSON.stringify({password}), {headers:{'Content-Type': 'application/json'}});
  }
  
}
0.14.7

4 years ago

0.14.5

4 years ago

0.14.6

4 years ago

0.14.4

4 years ago

0.14.2

4 years ago

0.14.3

4 years ago

0.13.6

4 years ago

0.13.7

4 years ago

0.13.8

4 years ago

0.13.9

4 years ago

0.13.0

4 years ago

0.13.1

4 years ago

0.13.2

4 years ago

0.13.3

4 years ago

0.13.4

4 years ago

0.13.5

4 years ago

0.14.0

4 years ago

0.14.1

4 years ago

0.12.4

4 years ago

0.12.5

4 years ago

0.12.3

4 years ago

0.12.2

4 years ago

0.12.1

4 years ago

0.12.0

5 years ago

0.11.0

5 years ago

0.11.1

5 years ago

0.10.0

5 years ago

0.9.0

5 years ago

0.8.0

5 years ago

0.7.4

5 years ago

0.7.5

5 years ago

0.7.2

5 years ago

0.7.1

5 years ago

0.7.0

5 years ago

0.6.1

5 years ago

0.5.0

5 years ago

0.6.0

5 years ago

0.4.5

6 years ago

0.4.4

6 years ago

0.4.3

6 years ago

0.4.2

6 years ago

0.4.1

6 years ago

0.4.0

6 years ago

0.3.11

6 years ago

0.3.10

6 years ago

0.3.9

6 years ago

0.3.8

6 years ago

0.3.7

6 years ago

0.3.6

6 years ago

0.3.5

6 years ago

0.3.4

6 years ago

0.3.3

6 years ago

0.3.2

6 years ago

0.3.1

6 years ago

0.3.0

6 years ago

0.2.31

6 years ago

0.2.30

6 years ago

0.2.29

6 years ago

0.2.28

6 years ago

0.2.26

6 years ago

0.2.25

6 years ago

0.2.24

6 years ago

0.2.23

6 years ago

0.2.22

6 years ago

0.2.21

6 years ago

0.2.20

6 years ago

0.2.19

6 years ago

0.2.18

6 years ago

0.2.17

6 years ago

0.2.16

6 years ago

0.2.15

6 years ago

0.2.14

6 years ago

0.2.13

6 years ago

0.2.12

6 years ago

0.2.11

6 years ago

0.2.10

6 years ago

0.2.9

6 years ago

0.2.8

6 years ago

0.2.7

6 years ago

0.2.6

6 years ago

0.2.4

6 years ago

0.2.3

6 years ago

0.2.2

6 years ago

0.2.1

6 years ago

0.2.0

6 years ago

0.1.1

6 years ago

0.1.0

6 years ago

0.0.3

6 years ago