OpenAPI client for @flipdish/authorization
This package provides a Typescript/JavaScript client for interacting with Flipdish's Authorization APIs over HTTP.
Internally the package utilizes the axios as its HTTP client.
``typescript
import {
AuthorizationApi,
Configuration,
ConfigurationDataApi,
type ErrorResponse,
Permissions,
UserPermissionsApi,
} from "@flipdish/authorization";
import { describe, expect, it, test } from "@jest/globals";
import axios, { isAxiosError } from "axios";
const basePath = "https://api.flipdish.co/auth/";
const bearerConfiguration = new Configuration({
basePath,
// to get the API key, you should follow these docs:
// https://developers.flipdish.com/docs/getting-started
accessToken: process.env.FLIPDISH_BEARER_TOKEN_PROD,
// if using in a browser set useDefaultUserAgent
// to true to prevent errors
// useDefaultUserAgent: true
});
const authorization = new AuthorizationApi(bearerConfiguration);
const configurationData = new ConfigurationDataApi(bearerConfiguration);
// mimic brower config where cookies will be sent automatically
// you shouldn't need to pass an axios instance as the cookies will be
// sent automatically by the browser
const userPermissions = new UserPermissionsApi(
new Configuration({ basePath }),
undefined,
axios.create({
headers: {
Cookie: FD-Authorization=${process.env.FD_AUTH_COOKIE_PROD_JM_CLIENT};,
},
}),
);
describe("Authorization Tests", () => {
describe("Authorization", () => {
test("List Permissions", async () => {
const permissionsResponse = await configurationData.listPermissions();
expect(permissionsResponse.status).toBe(200);
expect(permissionsResponse.data.permissions).toBeDefined();
expect(permissionsResponse.data.permissions.length).toBeGreaterThan(0);
expect(permissionsResponse.data.permissions).toContain(
Permissions.ViewApp,
);
expect(permissionsResponse.data.permissions).toContain(
Permissions.CreateApp,
);
expect(permissionsResponse.data.permissions).toContain(
Permissions.UpdateApp,
);
expect(permissionsResponse.data.permissions).toContain(
Permissions.ViewAppName,
);
expect(permissionsResponse.data.permissions).toContain(
Permissions.EditAppAssets,
);
});
test("List Feature Based Roles", async () => {
const featureBasedRolesResponse =
await configurationData.listFeatureBasedRoles();
expect(featureBasedRolesResponse.status).toBe(200);
expect(featureBasedRolesResponse.data.roles).toBeDefined();
expect(featureBasedRolesResponse.data.roles.length).toBeGreaterThan(0);
expect(featureBasedRolesResponse.data.roles).toContainEqual({
name: "OrgViewer",
permissions: ["ViewOrg"],
});
});
test("List named roles", async () => {
const namedRolesResponse = await configurationData.listRoles();
expect(namedRolesResponse.status).toBe(200);
expect(namedRolesResponse.data.roles).toBeDefined();
expect(namedRolesResponse.data.roles.length).toBeGreaterThan(0);
expect(namedRolesResponse.data.roles).toContainEqual("Admin");
});
describe("List User Permission Sets", () => {
it("should list user permission sets", async () => {
const userPermissionSetsResponse =
await userPermissions.listOwnPermissions("org42068");
expect(userPermissionSetsResponse.status).toBe(200);
expect(userPermissionSetsResponse.data.resources).toBeDefined();
expect(userPermissionSetsResponse.data.resources).toHaveProperty(
"org42068",
);
expect(
userPermissionSetsResponse.data.resources.org42068.permissions.length,
).toBeGreaterThan(0);
});
});
describe("Authenticate and Authorize", () => {
it("should authenticate and authorize with a valid FD-Authorization cookie", async () => {
const authorizationResponse =
await authorization.authenticateAndAuthorize({
headers: {
Cookie: FD-Authorization=${process.env.FD_AUTH_COOKIE_PROD};,
},
action: Permissions.AnyAuditLogs,
resource: {
id: "org12345",
type: "Org",
},
});
expect(authorizationResponse.status).toBe(200);
expect(authorizationResponse.data.authentication.authenticated).toBe(
true,
);
expect(authorizationResponse.data.authentication.principal?.type).toBe(
"User",
);
expect(authorizationResponse.data.authentication.principal?.id).toBe(
"8147747",
);
});
it("should not authenticate and authorize with an invalid FD-Authorization cookie", async () => {
try {
await authorization.authenticateAndAuthorize({
headers: {
Cookie: FD-Authorization=not-a-valid-cookie;,
},
action: Permissions.AnyAuditLogs,
resource: {
id: "org12345",
type: "Org",
},
});
} catch (error) {
if (isAxiosError
expect(error.response?.status).toBe(401);
expect(error.response?.data.message).toBe("Unauthenticated");
}
}
});
it("should authenticate and authorize with a valid Bearer token", async () => {
const authorizationResponse =
await authorization.authenticateAndAuthorize({
headers: {
Authorization: Bearer ${process.env.FLIPDISH_BEARER_TOKEN_PROD},
},
action: Permissions.AnyAuditLogs,
resource: {
id: "org12345",
type: "Org",
},
});
expect(authorizationResponse.status).toBe(200);
expect(authorizationResponse.data.authentication.authenticated).toBe(
true,
);
expect(authorizationResponse.data.authentication.principal?.type).toBe(
"User",
);
expect(authorizationResponse.data.authentication.principal?.id).toBe(
"8147747",
);
});
});
test("Authorize", async () => {
const authorizationResponse = await authorization.authorize({
principal: {
id: "12345",
type: "User",
},
action: Permissions.AnyAuditLogs,
resource: {
id: "org12345",
type: "Org",
},
});
expect(authorizationResponse.status).toBe(200);
expect(authorizationResponse.data.allowed).toBe(false);
expect(authorizationResponse.data.decision).toBe("DENY");
});
describe("Check is in role", () => {
it("should check if a user is in a role", async () => {
const isInRoleResponse = await authorization.checkIsInRole({
principal: {
id: "12345",
type: "User",
},
roles: ["Admin"],
});
expect(isInRoleResponse.status).toBe(200);
expect(isInRoleResponse.data.authorized).toBe(false);
});
it("should authenticate and check if a user is in a role with a valid FD-Authorization cookie", async () => {
const isInRoleResponse =
await authorization.authenticateAndCheckIsInRole({
headers: {
Cookie: FD-Authorization=${process.env.FD_AUTH_COOKIE_PROD};,
},
roles: ["Admin"],
});
expect(isInRoleResponse.status).toBe(200);
expect(isInRoleResponse.data.authorized).toBe(true);
});
it("should authenticate and check if a user is in a role with a valid Bearer token", async () => {
const isInRoleResponse =
await authorization.authenticateAndCheckIsInRole({
headers: {
Authorization: Bearer ${process.env.FLIPDISH_BEARER_TOKEN_PROD},
},
roles: ["Admin"],
});
expect(isInRoleResponse.status).toBe(200);
expect(isInRoleResponse.data.authorized).toBe(true);
});
});
});
});
`
The generated Node module can be used in the following environments:
Environment
* Node.js
* Webpack
* Browserify
Language level
* ES5 - you must have a Promises/A+ library installed
* ES6
Module system
* CommonJS
* ES6 module system
It can be used in both TypeScript and JavaScript. In TypeScript, the definition will be automatically resolved via package.json`. (Reference)