Skip to content

Commit 3179de2

Browse files
committed
Add boilerplate code
1 parent e199110 commit 3179de2

32 files changed

+3105
-1
lines changed

.eslintrc

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
{
2+
"extends": ["@ikscodes/eslint-config"],
3+
"parserOptions": {
4+
"project": [
5+
"./tsconfig.json",
6+
"./test/tsconfig.json"
7+
]
8+
},
9+
"rules": {
10+
"import/extensions": 0,
11+
"no-alert": 0,
12+
"@typescript-eslint/await-thenable": 0,
13+
"react/button-has-type": 0,
14+
"no-cond-assign": 0,
15+
"class-methods-use-this": 0,
16+
"no-underscore-dangle": 0,
17+
"no-useless-constructor": 0
18+
},
19+
"settings": {
20+
"import/resolver": {
21+
"typescript": {
22+
"directory": [
23+
"./tsconfig.json"
24+
"./test/tsconfig.json"
25+
]
26+
}
27+
}
28+
}
29+
}

.gitignore

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# See https://help.github.com/ignore-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/dist
6+
7+
# misc
8+
npm-debug.log*
9+
yarn-error.log*
10+
.DS_Store
11+
12+
# Use Yarn!
13+
package-lock.json

.prettierrc.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module.exports = require('@ikscodes/prettier-config');

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2018 Fortmatic Inc.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+29-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,29 @@
1-
# magic-admin-js
1+
# Magic Authentication Admin Javascript SDK
2+
3+
The Magic Admin SDK lets developers secure endpoints in their Express-based NodeJS application via easy-to-use middleware.
4+
5+
## Documentation
6+
7+
See the [Developer Documentation](https://docs.fortmatic.com).
8+
9+
## Installation
10+
11+
Integrating your NodeJS application with Magic Authentication will require our NPM package:
12+
13+
```zsh
14+
npm install --save @magic-sdk/admin
15+
```
16+
17+
## Usage
18+
Sign up or log in to your [Developer Dashboard](https://dashboard.fortmatic.com) to receive API keys.
19+
20+
21+
```jspx
22+
const Magic = require('@magic-sdk/admin');
23+
24+
// Create the Admin SDK instance
25+
const magic = new Magic(‘YOUR_DEVELOPER_SECRET_KEY’);
26+
27+
// Apply Express middleware
28+
app.use(magic.middlewares.express);
29+
```

config/tsconfig.base.json

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"compilerOptions": {
3+
"lib": ["es2018"],
4+
"module": "commonjs",
5+
"moduleResolution": "node",
6+
"target": "es5",
7+
"strict": true,
8+
"allowSyntheticDefaultImports": true,
9+
"experimentalDecorators": true,
10+
"noImplicitReturns": true,
11+
"noImplicitThis": true,
12+
"esModuleInterop": true,
13+
"downlevelIteration": true,
14+
"resolveJsonModule": true,
15+
"allowJs": true,
16+
"sourceMap": true,
17+
"declaration": true,
18+
},
19+
"include": ["../src/**/*.ts"],
20+
"exclude": ["../node_modules"]
21+
}

config/tsconfig.sdk.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "./tsconfig.base.json",
3+
"compilerOptions": {
4+
"outDir": "../dist",
5+
},
6+
"include": ["../src/admin-sdk"]
7+
}

config/tsconfig.test.json

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"extends": "./tsconfig.base.json",
3+
"compilerOptions": {
4+
"module": "commonjs",
5+
"target": "es6",
6+
"strict": false,
7+
"noImplicitAny": false,
8+
"downlevelIteration": true,
9+
"esModuleInterop": true
10+
},
11+
"include": ["../test/**/*.ts"]
12+
}

package.json

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"name": "@magic-sdk/admin",
3+
"version": "0.0.1",
4+
"description": "Magic Authentication Admin Javascript SDK",
5+
"author": "Fortmatic <[email protected]> (https://fortmatic.com/)",
6+
"license": "MIT",
7+
"repository": {
8+
"type": "git",
9+
"url": "https://github.com/fortmatic/magic-admin-js"
10+
},
11+
"main": "dist/index.js",
12+
"types": "dist/index.d.ts",
13+
"scripts": {
14+
"start": "npm run clean:build && ./scripts/start.sh",
15+
"start:sdk": "tsc -w -p ./config/tsconfig.sdk.json",
16+
"start:e2e": "ts-node src/node-e2e/app.ts",
17+
"build": "npm run clean:build && ./scripts/build.sh",
18+
"clean": "npm-run-all -s clean:*",
19+
"clean:build": "rimraf dist",
20+
"clean_node_modules": "rimraf node_modules",
21+
"lint": "tslint --fix ."
22+
},
23+
"devDependencies": {
24+
"@ikscodes/eslint-config": "^6.2.0",
25+
"@ikscodes/prettier-config": "^1.0.0",
26+
"@types/eth-sig-util": "^2.1.0",
27+
"@types/express": "^4.17.2",
28+
"@types/node": "^13.1.2",
29+
"@types/node-fetch": "^2.5.4",
30+
"@typescript-eslint/eslint-plugin": "^2.15.0",
31+
"eslint": "^6.7.2",
32+
"eslint-import-resolver-typescript": "^2.0.0",
33+
"eslint-plugin-import": "^2.18.2",
34+
"eslint-plugin-jsx-a11y": "^6.2.3",
35+
"eslint-plugin-prettier": "^3.1.2",
36+
"eslint-plugin-react": "^7.15.1",
37+
"eslint-plugin-react-hooks": "^1.7.0",
38+
"npm-run-all": "~4.1.5",
39+
"prettier": "^1.19.1",
40+
"rimraf": "~3.0.0",
41+
"ts-node": "~8.5.2",
42+
"tslint": "~5.20.1",
43+
"typescript": "~3.7.2"
44+
},
45+
"dependencies": {
46+
"eth-sig-util": "2.1.2",
47+
"ethereumjs-util": "^6.2.0",
48+
"express": "^4.17.1",
49+
"node-fetch": "^2.6.0"
50+
},
51+
"husky": {
52+
"hooks": {
53+
"pre-commit": "lint-staged"
54+
}
55+
},
56+
"lint-staged": {
57+
"*.{ts,tsx}": "eslint --fix"
58+
}
59+
}

scripts/build.sh

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/usr/bin/env bash
2+
3+
echo
4+
echo "Building Magic Admin SDK for production."
5+
echo
6+
7+
# Increase memory limit for Node
8+
export NODE_OPTIONS=--max_old_space_size=4096
9+
10+
export NODE_ENV=production
11+
12+
npx tsc -p ./config/tsconfig.sdk.json

scripts/start.sh

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/usr/bin/env bash
2+
3+
echo
4+
echo "Building Magic Admin SDK for development."
5+
echo
6+
7+
# Increase memory limit for Node
8+
export NODE_OPTIONS=--max_old_space_size=4096
9+
10+
export NODE_ENV=development
11+
12+
npx npm-run-all -p start:* -l

scripts/test.sh

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#!/usr/bin/env bash
2+
3+
echo
4+
echo "Running unit tests..."
5+
echo
6+
7+
# Increase memory limit for Node
8+
export NODE_OPTIONS=--max_old_space_size=4096
9+
10+
export NODE_ENV=test
11+
12+
if [ -n "$1" ]; then
13+
input=$(echo $(npx glob $1))
14+
fi
15+
16+
export TS_NODE_PROJECT="test/tsconfig.json"
17+
npx nyc --reporter=lcov --reporter=text-summary ava $input

src/admin-sdk/core/sdk-exceptions.ts

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { ErrorCode } from '../types';
2+
3+
// --- Base SDK error class
4+
5+
export class MagicAdminSDKError extends Error {
6+
__proto__ = Error;
7+
8+
constructor(public code: ErrorCode, message: string) {
9+
super(`Magic Admin SDK Error: [${code}] ${message}`);
10+
Object.setPrototypeOf(this, MagicAdminSDKError.prototype);
11+
}
12+
}
13+
14+
// --- SDK error factories
15+
16+
export function createMissingAuthHeaderError() {
17+
return new MagicAdminSDKError(
18+
ErrorCode.MissingAuthHeader,
19+
'Missing authorization header. Request failed authentication.',
20+
);
21+
}
22+
23+
export function createTokenExpiredError() {
24+
return new MagicAdminSDKError(ErrorCode.TokenExpired, 'DID Token has expired. Request failed authentication.');
25+
}
26+
27+
export function createIncorrectSignerAddressError() {
28+
return new MagicAdminSDKError(
29+
ErrorCode.IncorrectSignerAddress,
30+
'Incorrect signer address for DID Token. Request failed authentication.',
31+
);
32+
}
33+
34+
export function createFailedRecoveringProofError() {
35+
return new MagicAdminSDKError(
36+
ErrorCode.FailedRecoveryProof,
37+
'Failed to recover proof. Request failed authentication.',
38+
);
39+
}
40+
41+
export function createApiKeyMissingError() {
42+
return new MagicAdminSDKError(
43+
ErrorCode.ApiKeyMissing,
44+
'Please provide a secret Fortmatic API key that you acquired from the developer dashboard.',
45+
);
46+
}

src/admin-sdk/core/sdk.ts

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { MiddlewaresModule } from '../modules/middlewares';
2+
import { TokenModule } from '../modules/token';
3+
import { UsersModule } from '../modules/users';
4+
5+
export class MagicAdminSDK {
6+
public readonly apiBaseUrl = 'https://api.fortmatic.com';
7+
8+
/**
9+
* Contains token validation middlewares for various NodeJS server frameworks.
10+
*/
11+
public readonly middlewares: MiddlewaresModule;
12+
13+
/**
14+
* Contains utilities for interacting with Decentralized Identity Tokens
15+
* (DIDTs).
16+
*/
17+
public readonly token: TokenModule;
18+
19+
/**
20+
* Contains utilities for interacting with your Magic Authentication user
21+
* model.
22+
*/
23+
public readonly users: UsersModule;
24+
25+
constructor(public readonly secretApiKey: string) {
26+
// Assign API Modules
27+
this.middlewares = new MiddlewaresModule(this);
28+
this.token = new TokenModule(this);
29+
this.users = new UsersModule(this);
30+
}
31+
}

src/admin-sdk/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { MagicAdminSDK as default } from './core/sdk';
2+
export * from './types';

src/admin-sdk/modules/base-module.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { MagicAdminSDK } from '../core/sdk';
2+
3+
export class BaseModule {
4+
constructor(protected readonly sdk: MagicAdminSDK) {}
5+
}
+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { Request, Response, NextFunction } from 'express';
2+
import { BaseModule } from '../base-module';
3+
import { createMissingAuthHeaderError } from '../../core/sdk-exceptions';
4+
5+
export class MiddlewaresModule extends BaseModule {
6+
public express = async (req: Request, res: Response, next: NextFunction) => {
7+
const authorizationHeader = req?.headers?.authorization;
8+
if (!authorizationHeader || !authorizationHeader.toLowerCase().startsWith('bearer ')) {
9+
res.status(401).send(createMissingAuthHeaderError().message);
10+
}
11+
try {
12+
const DIDToken = authorizationHeader!.substring(7); // Strips Bearer
13+
await this.sdk.token.validate(DIDToken);
14+
next();
15+
} catch (err) {
16+
res.status(401).send(err.message);
17+
}
18+
};
19+
}

0 commit comments

Comments
 (0)