@fortmatic/admin
Advanced tools
Comparing version 0.0.4 to 0.0.7
export declare enum HTTPMessages { | ||
ERROR_MISSING_AUTH_HEADER = "[fortmatic] Missing authorization header. Request failed authentication.", | ||
ERROR_VALIDATING_CHMSG = "[fortmatic] Unable to validate challenge message. Request failed authentication.", | ||
ERROR_DAT_EXPIRED = "[fortmatic] Decentralized Access Token has expired. Request failed authentication.", | ||
ERROR_INCORRECT_SIGNER_ADDR = "[fortmatic] Incorrect signer address for Decentralized Access Token. Request failed authentication.", | ||
ERROR_DIDT_EXPIRED = "[fortmatic] DID Token has expired. Request failed authentication.", | ||
ERROR_INCORRECT_SIGNER_ADDR = "[fortmatic] Incorrect signer address for DID Token. Request failed authentication.", | ||
ERROR_FAILED_RECOVERING_PROOF = "[fortmatic] Failed to recover proof. Request failed authentication.", | ||
ERROR_FAILED_RETRIEVING_CHALLENGE_MESSAGE = "[fortmatic] Failed retrieving challenge message for user address.", | ||
SUCCESS = "[fortmatic] Authentication succeeded." | ||
} |
@@ -6,9 +6,7 @@ "use strict"; | ||
HTTPMessages["ERROR_MISSING_AUTH_HEADER"] = "[fortmatic] Missing authorization header. Request failed authentication."; | ||
HTTPMessages["ERROR_VALIDATING_CHMSG"] = "[fortmatic] Unable to validate challenge message. Request failed authentication."; | ||
HTTPMessages["ERROR_DAT_EXPIRED"] = "[fortmatic] Decentralized Access Token has expired. Request failed authentication."; | ||
HTTPMessages["ERROR_INCORRECT_SIGNER_ADDR"] = "[fortmatic] Incorrect signer address for Decentralized Access Token. Request failed authentication."; | ||
HTTPMessages["ERROR_DIDT_EXPIRED"] = "[fortmatic] DID Token has expired. Request failed authentication."; | ||
HTTPMessages["ERROR_INCORRECT_SIGNER_ADDR"] = "[fortmatic] Incorrect signer address for DID Token. Request failed authentication."; | ||
HTTPMessages["ERROR_FAILED_RECOVERING_PROOF"] = "[fortmatic] Failed to recover proof. Request failed authentication."; | ||
HTTPMessages["ERROR_FAILED_RETRIEVING_CHALLENGE_MESSAGE"] = "[fortmatic] Failed retrieving challenge message for user address."; | ||
HTTPMessages["SUCCESS"] = "[fortmatic] Authentication succeeded."; | ||
})(HTTPMessages = exports.HTTPMessages || (exports.HTTPMessages = {})); | ||
//# sourceMappingURL=http-messages.js.map |
@@ -1,4 +0,7 @@ | ||
import { DATValidator } from './dat-validator'; | ||
export declare class Fortmatic extends DATValidator { | ||
constructor(secretApiKey?: string); | ||
export declare class Fortmatic { | ||
constructor(); | ||
validateToken(DIDToken: string): Promise<void>; | ||
decodeToken(DIDToken: string): any[]; | ||
getUserPublicAddress(authorizationHeader: string): string; | ||
expressMiddleware: (req: any, res: any, next: Function) => Promise<void>; | ||
} |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
return new (P || (P = Promise))(function (resolve, reject) { | ||
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } | ||
step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
}); | ||
}; | ||
var __generator = (this && this.__generator) || function (thisArg, body) { | ||
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
function verb(n) { return function (v) { return step([n, v]); }; } | ||
function step(op) { | ||
if (f) throw new TypeError("Generator is already executing."); | ||
while (_) try { | ||
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
if (y = 0, t) op = [op[0] & 2, t.value]; | ||
switch (op[0]) { | ||
case 0: case 1: t = op; break; | ||
case 4: _.label++; return { value: op[1], done: false }; | ||
case 5: _.label++; y = op[1]; op = [0]; continue; | ||
case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
default: | ||
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
if (t[2]) _.ops.pop(); | ||
_.trys.pop(); continue; | ||
} | ||
op = body.call(thisArg, _); | ||
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
} | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; | ||
result["default"] = mod; | ||
return result; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var eth_sig_util_1 = __importDefault(require("eth-sig-util")); | ||
var ethUtil = __importStar(require("ethereumjs-util")); | ||
var http_messages_1 = require("../constants/http-messages"); | ||
var Fortmatic = /** @class */ (function () { | ||
function Fortmatic() { | ||
var _this = this; | ||
this.expressMiddleware = function (req, res, next) { return __awaiter(_this, void 0, void 0, function () { | ||
var authorizationHeader, DIDToken, err_1; | ||
var _a, _b; | ||
return __generator(this, function (_c) { | ||
switch (_c.label) { | ||
case 0: | ||
authorizationHeader = (_b = (_a = req) === null || _a === void 0 ? void 0 : _a.headers) === null || _b === void 0 ? void 0 : _b.authorization; | ||
if (!authorizationHeader || !authorizationHeader.toLowerCase().startsWith('bearer ')) { | ||
res.status(401).send(http_messages_1.HTTPMessages.ERROR_MISSING_AUTH_HEADER); | ||
} | ||
_c.label = 1; | ||
case 1: | ||
_c.trys.push([1, 3, , 4]); | ||
DIDToken = authorizationHeader.substring(7); | ||
return [4 /*yield*/, this.validateToken(DIDToken)]; | ||
case 2: | ||
_c.sent(); | ||
next(); | ||
return [3 /*break*/, 4]; | ||
case 3: | ||
err_1 = _c.sent(); | ||
res.status(401).send(err_1.message); | ||
return [3 /*break*/, 4]; | ||
case 4: return [2 /*return*/]; | ||
} | ||
}); | ||
}); }; | ||
} | ||
Fortmatic.prototype.validateToken = function (DIDToken) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var recoveredSignerAddress, claimedIssuer, claimJSONObject, decodedDIDToken, proof, claim, ecRecoverMsgParams; | ||
return __generator(this, function (_a) { | ||
recoveredSignerAddress = ''; | ||
claimedIssuer = ''; | ||
try { | ||
decodedDIDToken = JSON.parse(Buffer.from(DIDToken, 'base64').toString('binary')); | ||
proof = decodedDIDToken[0]; | ||
claim = decodedDIDToken[1]; | ||
claimJSONObject = JSON.parse(claim); | ||
ecRecoverMsgParams = { | ||
data: ethUtil.bufferToHex(Buffer.from(claim, 'utf8')), | ||
sig: proof | ||
}; | ||
recoveredSignerAddress = eth_sig_util_1.default.recoverPersonalSignature(ecRecoverMsgParams); | ||
claimedIssuer = claimJSONObject.iss.split(':')[2]; | ||
} | ||
catch (err) { | ||
throw new Error(http_messages_1.HTTPMessages.ERROR_FAILED_RECOVERING_PROOF); | ||
} | ||
if (claimedIssuer.toLowerCase() !== recoveredSignerAddress.toLowerCase()) { | ||
throw new Error(http_messages_1.HTTPMessages.ERROR_INCORRECT_SIGNER_ADDR); | ||
} | ||
if (claimJSONObject.ext < Math.floor(Date.now() / 1000) - 30) { | ||
throw new Error(http_messages_1.HTTPMessages.ERROR_DIDT_EXPIRED); | ||
} | ||
return [2 /*return*/]; | ||
}); | ||
}); | ||
}; | ||
return function (d, b) { | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
Fortmatic.prototype.decodeToken = function (DIDToken) { | ||
return JSON.parse(Buffer.from(DIDToken, 'base64').toString('binary')); | ||
}; | ||
})(); | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var fm_challenge_message_service_1 = require("../services/fm-challenge-message-service"); | ||
var dat_validator_1 = require("./dat-validator"); | ||
var Fortmatic = /** @class */ (function (_super) { | ||
__extends(Fortmatic, _super); | ||
function Fortmatic(secretApiKey) { | ||
return _super.call(this, new fm_challenge_message_service_1.FortmaticChallengeMessageService(secretApiKey)) || this; | ||
} | ||
Fortmatic.prototype.getUserPublicAddress = function (authorizationHeader) { | ||
var _a; | ||
var DIDToken = authorizationHeader.substring(7); | ||
var decodedDIDToken = this.decodeToken(DIDToken); | ||
var claimJSONObject = JSON.parse(decodedDIDToken[1]); | ||
var claimedIssuer = (_a = claimJSONObject) === null || _a === void 0 ? void 0 : _a.iss.split(':')[2]; | ||
return claimedIssuer; | ||
}; | ||
return Fortmatic; | ||
}(dat_validator_1.DATValidator)); | ||
}()); | ||
exports.Fortmatic = Fortmatic; | ||
//# sourceMappingURL=fortmatic.js.map |
export { Fortmatic as default } from './core/fortmatic'; | ||
export { DATValidator } from './core/dat-validator'; | ||
export * from './types'; |
"use strict"; | ||
function __export(m) { | ||
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
} | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var fortmatic_1 = require("./core/fortmatic"); | ||
exports.default = fortmatic_1.Fortmatic; | ||
var dat_validator_1 = require("./core/dat-validator"); | ||
exports.DATValidator = dat_validator_1.DATValidator; | ||
__export(require("./types")); | ||
//# sourceMappingURL=index.js.map |
@@ -1,15 +0,3 @@ | ||
/** | ||
* The generic shape of a "challenge message" service, an integral part of the | ||
* Decentralized Access Token ecosystem. | ||
*/ | ||
export declare abstract class ChallengeMessageService { | ||
protected readonly secretApiKey?: string | undefined; | ||
constructor(secretApiKey?: string | undefined); | ||
abstract getChallengeMessage(publicAddress: string): Promise<string | undefined>; | ||
abstract resetChallengeMessage(publicAddress: string): Promise<boolean>; | ||
} | ||
/** The shape of metadata encoded within a Decentralized Access Token. */ | ||
export interface Declarations { | ||
addr: string; | ||
chmsg: string; | ||
/** The shape of metadata encoded within a DID Token. */ | ||
export interface Claim { | ||
iat: number; | ||
@@ -21,13 +9,3 @@ ext: number; | ||
nbf: number; | ||
dti: number; | ||
tid: number; | ||
} | ||
/** | ||
* The shape of a decoded Decentralized Access Token claim. This is represented | ||
* in an EIP-712 "typed data" message. | ||
*/ | ||
export interface Claim { | ||
types: any; | ||
primaryType: string; | ||
domain: any; | ||
message: Declarations; | ||
} |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
/** | ||
* The generic shape of a "challenge message" service, an integral part of the | ||
* Decentralized Access Token ecosystem. | ||
*/ | ||
var ChallengeMessageService = /** @class */ (function () { | ||
function ChallengeMessageService(secretApiKey) { | ||
this.secretApiKey = secretApiKey; | ||
} | ||
return ChallengeMessageService; | ||
}()); | ||
exports.ChallengeMessageService = ChallengeMessageService; | ||
//# sourceMappingURL=index.js.map |
{ | ||
"name": "@fortmatic/admin", | ||
"version": "0.0.4", | ||
"version": "0.0.7", | ||
"description": "Fortmatic Javascript Admin SDK", | ||
@@ -39,4 +39,5 @@ "author": "Fortmatic <team@fortmatic.com> (https://fortmatic.com/)", | ||
"eth-sig-util": "2.1.2", | ||
"ethereumjs-util": "^6.2.0", | ||
"node-fetch": "^2.6.0" | ||
} | ||
} |
export enum HTTPMessages { | ||
ERROR_MISSING_AUTH_HEADER = '[fortmatic] Missing authorization header. Request failed authentication.', | ||
ERROR_VALIDATING_CHMSG = '[fortmatic] Unable to validate challenge message. Request failed authentication.', | ||
ERROR_DAT_EXPIRED = '[fortmatic] Decentralized Access Token has expired. Request failed authentication.', | ||
ERROR_INCORRECT_SIGNER_ADDR = '[fortmatic] Incorrect signer address for Decentralized Access Token. Request failed authentication.', | ||
ERROR_DIDT_EXPIRED = '[fortmatic] DID Token has expired. Request failed authentication.', | ||
ERROR_INCORRECT_SIGNER_ADDR = '[fortmatic] Incorrect signer address for DID Token. Request failed authentication.', | ||
ERROR_FAILED_RECOVERING_PROOF = '[fortmatic] Failed to recover proof. Request failed authentication.', | ||
ERROR_FAILED_RETRIEVING_CHALLENGE_MESSAGE = '[fortmatic] Failed retrieving challenge message for user address.', | ||
SUCCESS = '[fortmatic] Authentication succeeded.', | ||
} |
@@ -1,8 +0,74 @@ | ||
import { FortmaticChallengeMessageService } from '../services/fm-challenge-message-service'; | ||
import { DATValidator } from './dat-validator'; | ||
import ethSigUtil from 'eth-sig-util'; | ||
import * as ethUtil from 'ethereumjs-util'; | ||
import { HTTPMessages } from '../constants/http-messages'; | ||
import { Claim } from '../types'; | ||
export class Fortmatic extends DATValidator { | ||
constructor(secretApiKey?: string) { | ||
super(new FortmaticChallengeMessageService(secretApiKey)); | ||
export class Fortmatic { | ||
constructor() { } | ||
public async validateToken(DIDToken: string) { | ||
let recoveredSignerAddress = ''; | ||
let claimedIssuer = ''; | ||
let claimJSONObject; | ||
try { | ||
/* Decoded DIDToken: [proof, claim] */ | ||
const decodedDIDToken = JSON.parse(Buffer.from(DIDToken, 'base64').toString('binary')); | ||
const proof = decodedDIDToken[0] as string; | ||
const claim = decodedDIDToken[1] as string; | ||
claimJSONObject = JSON.parse(claim) as Claim; | ||
/** | ||
* Use ecRecover on the Proof, to validate if it recovers to the expected | ||
* Claim, and expected Signer Address | ||
*/ | ||
const ecRecoverMsgParams = { | ||
data: ethUtil.bufferToHex(Buffer.from(claim, 'utf8')), | ||
sig: proof | ||
}; | ||
recoveredSignerAddress = ethSigUtil.recoverPersonalSignature(ecRecoverMsgParams); | ||
claimedIssuer = claimJSONObject.iss.split(':')[2]; | ||
} | ||
catch (err) { | ||
throw new Error(HTTPMessages.ERROR_FAILED_RECOVERING_PROOF); | ||
} | ||
if (claimedIssuer.toLowerCase() !== recoveredSignerAddress.toLowerCase()) { | ||
throw new Error(HTTPMessages.ERROR_INCORRECT_SIGNER_ADDR); | ||
} | ||
if (claimJSONObject.ext < Math.floor(Date.now() / 1000) - 30) { | ||
throw new Error(HTTPMessages.ERROR_DIDT_EXPIRED); | ||
} | ||
} | ||
public decodeToken(DIDToken: string): any[] { | ||
return JSON.parse(Buffer.from(DIDToken, 'base64').toString('binary')) as any[]; | ||
} | ||
public getUserPublicAddress(authorizationHeader: string): string { | ||
const DIDToken = authorizationHeader.substring(7); | ||
const decodedDIDToken = this.decodeToken(DIDToken) as any[]; | ||
const claimJSONObject = JSON.parse(decodedDIDToken[1]) as Claim; | ||
const claimedIssuer = claimJSONObject?.iss.split(':')[2]; | ||
return claimedIssuer; | ||
} | ||
public expressMiddleware = async (req: any, res: any, next: Function) => { | ||
const authorizationHeader = req?.headers?.authorization; | ||
if (!authorizationHeader || !authorizationHeader.toLowerCase().startsWith('bearer ')) { | ||
res.status(401).send(HTTPMessages.ERROR_MISSING_AUTH_HEADER); | ||
} | ||
try { | ||
const DIDToken = authorizationHeader.substring(7); /* Strips Bearer */ | ||
await this.validateToken(DIDToken); | ||
next(); | ||
} catch (err) { | ||
res.status(401).send(err.message); | ||
} | ||
}; | ||
} |
export { Fortmatic as default } from './core/fortmatic'; | ||
export { DATValidator } from './core/dat-validator'; | ||
export * from './types'; |
@@ -1,33 +0,10 @@ | ||
/** | ||
* The generic shape of a "challenge message" service, an integral part of the | ||
* Decentralized Access Token ecosystem. | ||
*/ | ||
export abstract class ChallengeMessageService { | ||
constructor(protected readonly secretApiKey?: string) {} | ||
abstract getChallengeMessage(publicAddress: string): Promise<string | undefined>; | ||
abstract resetChallengeMessage(publicAddress: string): Promise<boolean>; | ||
} | ||
/** The shape of metadata encoded within a Decentralized Access Token. */ | ||
export interface Declarations { | ||
addr: string; // Signer address | ||
chmsg: string; // Challenge Message | ||
/** The shape of metadata encoded within a DID Token. */ | ||
export interface Claim { | ||
iat: number; // Issued At Timestamp | ||
ext: number; // Expiration Timestamp | ||
iss: string; // Issuer. Defaults to Fortmatic | ||
iss: string; // Issuer of DID Token | ||
sub: string; // Subject | ||
aud: string; // Audience | ||
nbf: number; // Not Before Timestamp | ||
dti: number; // Decentralized Token ID | ||
tid: number; // DID Token ID | ||
} | ||
/** | ||
* The shape of a decoded Decentralized Access Token claim. This is represented | ||
* in an EIP-712 "typed data" message. | ||
*/ | ||
export interface Claim { | ||
types: any; | ||
primaryType: string; | ||
domain: any; | ||
message: Declarations; // Signed declarations for this claim. | ||
} |
@@ -12,3 +12,3 @@ // Import controllers | ||
/* Fortmatic admin SDK instance */ | ||
const fortmatic = new Fortmatic('4fffade6d3c36a31cc09026b96bc1966e9555eb7774738e4b2cf5c82605971de'); | ||
const fortmatic = new Fortmatic(); | ||
@@ -34,11 +34,2 @@ /* Entry point for middleWare */ | ||
/* | ||
* Get user likes | ||
*/ | ||
app.get('/invalidate', (req: any, res: any) => { | ||
const signerAddress = fortmatic.getUserPublicAddress(req.headers.authorization); | ||
fortmatic.invalidateTokenBySignerAddress(signerAddress); | ||
res.send({ status: 'ok' }); | ||
}); | ||
/* | ||
* Get user comments | ||
@@ -45,0 +36,0 @@ */ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
0
22277
3
30
394
1
+ Addedethereumjs-util@^6.2.0
+ Added@types/bn.js@4.11.6(transitive)
+ Addedethereumjs-util@6.2.1(transitive)