From c36cdc095e2ae296c29215508bf62b68bccce08d Mon Sep 17 00:00:00 2001 From: Neil Rackett Date: Mon, 29 Jul 2024 14:32:12 +0100 Subject: [PATCH] Added magicLogin.create() method to resolve issue #35 --- .gitignore | 3 +++ package.json | 28 +++++++++++++--------------- src/index.ts | 51 ++++++++++++++++++++++++++++++++++----------------- 3 files changed, 50 insertions(+), 32 deletions(-) diff --git a/.gitignore b/.gitignore index 4c9d7c3..76ab4f4 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ .DS_Store node_modules dist +lock.json + *-lock.yaml + *.lock \ No newline at end of file diff --git a/package.json b/package.json index 9d1e3e9..8b32a3c 100644 --- a/package.json +++ b/package.json @@ -11,25 +11,23 @@ "node": ">=10" }, "scripts": { - "start": "tsdx watch", - "build": "tsdx build", - "test": "tsdx test", - "lint": "tsdx lint", - "prepare": "tsdx build", + "start": "dts watch", + "build": "dts build", + "test": "dts test", + "lint": "dts lint", + "prepare": "dts build", "size": "size-limit", "analyze": "size-limit --why" }, - "peerDependencies": {}, "husky": { - "hooks": { - "pre-commit": "tsdx lint" - } + "hooks": {} }, "prettier": { "printWidth": 80, "semi": true, "singleQuote": true, - "trailingComma": "es5" + "trailingComma": "es5", + "endOfLine": "auto" }, "name": "passport-magic-login", "description": "Passwordless authentication with magic links for Passport.js 🔑", @@ -47,17 +45,17 @@ ], "devDependencies": { "@size-limit/preset-small-lib": "^4.9.1", - "@types/express": "^4.17.11", + "@types/express": "^4.17.21", "@types/jsonwebtoken": "^9.0.0", - "@types/passport": "^1.0.5", - "husky": "^4.3.7", + "@types/node": "^14.14.20", + "@types/passport": "^1.0.16", + "dts-cli": "^2.0.5", + "husky": "^9.1.3", "size-limit": "^4.9.1", - "tsdx": "^0.14.1", "tslib": "^2.1.0", "typescript": "^4.1.3" }, "dependencies": { - "@types/node": "^14.14.20", "jsonwebtoken": "^9.0.0" } } diff --git a/src/index.ts b/src/index.ts index 145f864..3f32051 100644 --- a/src/index.ts +++ b/src/index.ts @@ -25,6 +25,16 @@ interface Options { confirmUrl?: string; } +interface Payload { + [key: string]: any; + destination: string; +} + +interface MagicLinkInfo { + href: string; + code: string; +} + class MagicLoginStrategy { name: string = 'magiclogin'; @@ -50,7 +60,7 @@ class MagicLoginStrategy { return self.fail(message); } - const verifyCallback = function( + const verifyCallback = function ( err?: Error | null, user?: Object, info?: any @@ -68,7 +78,7 @@ class MagicLoginStrategy { } send = (req: Request, res: Response): void => { - const payload = req.method === 'GET' ? req.query : req.body; + const payload: Payload = req.method === 'GET' ? req.query : req.body; if ( req.method === 'POST' && !req.headers['content-type']?.match('application/json') @@ -84,23 +94,10 @@ class MagicLoginStrategy { return; } - const code = Math.floor(Math.random() * 90000) + 10000 + ''; - const jwt = generateToken( - this._options.secret, - { - ...payload, - code, - }, - this._options.jwtOptions - ); + const { href, code } = this.create(payload); this._options - .sendMagicLink( - payload.destination, - `${this._options.callbackUrl}?token=${jwt}`, - code, - req - ) + .sendMagicLink(payload.destination, href, code, req) .then(() => { res.json({ success: true, code }); }) @@ -110,6 +107,26 @@ class MagicLoginStrategy { }); }; + create(destination: string): MagicLinkInfo; + create(payload: Payload): MagicLinkInfo; + create(payload: Payload | string): MagicLinkInfo { + if (typeof payload === 'string') { + payload = { destination: payload }; + } + const code = Math.floor(Math.random() * 90000) + 10000 + ''; + const jwt = generateToken( + this._options.secret, + { + ...payload, + code, + }, + this._options.jwtOptions + ); + const href = `${this._options.callbackUrl}?token=${jwt}`; + + return { href, code }; + } + /** @deprecated */ confirm = (req: Request, res: Response): void => { console.warn(