Comparing version 2.0.8 to 2.0.13-alpha.0
@@ -24,2 +24,4 @@ import { Context } from 'egg'; | ||
private unauthorizedRedirectIgnore?; | ||
private cookieDomain?; | ||
private callbackWhitelist?; | ||
private loginHandler?; | ||
@@ -45,5 +47,5 @@ private authHandler?; | ||
private saveJsonWebTokenToHeader; | ||
private assertCallbackLegal; | ||
private assertCallbackWhitelist; | ||
private formatState; | ||
private parseState; | ||
} |
@@ -7,173 +7,27 @@ "use strict"; | ||
class KauthProvider { | ||
maxAge = 2147483647; | ||
moziAuthenticator; | ||
googleAuthenticator; | ||
miniprogramAuthenticator; | ||
subjectProvider; | ||
jwtProvider; | ||
router; | ||
permissionHandler; | ||
moziTokenUri; | ||
moziBindUri; | ||
moziPrompt; | ||
googleTokenUri; | ||
googleBindUri; | ||
googlePrompt; | ||
miniprogramTokenUri; | ||
miniprogramBindUri; | ||
miniprogramPrompt; | ||
logoutRedirectUri; | ||
unautorizedRedirectUri; | ||
unauthorizedRedirectIgnore; | ||
cookieDomain; | ||
callbackWhitelist; | ||
loginHandler; | ||
authHandler; | ||
constructor(kauthConfig) { | ||
this.maxAge = 2147483647; | ||
this.dispatch = async (ctx, next) => { | ||
await this.router.dispatch(ctx, next); | ||
}; | ||
this.logout = async (ctx) => { | ||
const { callback } = ctx.request.query; | ||
ctx.cookies.set('Authorization', '', { | ||
path: '/', | ||
httpOnly: true, | ||
maxAge: 0, | ||
}); | ||
if (callback) { | ||
ctx.redirect(callback); | ||
return; | ||
} | ||
ctx.redirect(this.logoutRedirectUri); | ||
}; | ||
this.redirectMoziAuthorizeUri = async (ctx) => { | ||
const { type, origin, callback = origin } = ctx.request.query; | ||
this.assertCallbackLegal(callback, origin); | ||
if (type === 'binding') { | ||
const userId = await this.getBindingUserIdFromCookie(ctx); | ||
if (!userId) { | ||
return this.illegalToBindAccount(ctx); | ||
} | ||
const state = this.formatState({ origin, userId, callback }); | ||
const url = await this.moziAuthenticator.authorizeURL(origin + this.moziBindUri, state, this.moziPrompt); | ||
return ctx.redirect(url); | ||
} | ||
const state = this.formatState({ origin, callback }); | ||
const url = await this.moziAuthenticator.authorizeURL(origin + this.moziTokenUri, state, this.moziPrompt); | ||
ctx.redirect(url); | ||
}; | ||
this.redirectGoogleAuthorizeUri = async (ctx) => { | ||
const { type, origin, callback = origin } = ctx.request.query; | ||
this.assertCallbackLegal(callback, origin); | ||
if (type === 'binding') { | ||
const userId = await this.getBindingUserIdFromCookie(ctx); | ||
if (!userId) { | ||
return this.illegalToBindAccount(ctx); | ||
} | ||
const state = this.formatState({ origin, userId, callback }); | ||
const url = await this.googleAuthenticator.authorizeURL(origin + this.googleBindUri, state, this.googlePrompt); | ||
return ctx.redirect(url); | ||
} | ||
const state = this.formatState({ origin, callback }); | ||
const url = await this.googleAuthenticator.authorizeURL(origin + this.googleTokenUri, state, this.googlePrompt); | ||
ctx.redirect(url); | ||
}; | ||
this.redirectMiniProgarmAuthorizeUri = async (ctx) => { | ||
const { type, origin, callback = origin } = ctx.request.query; | ||
this.assertCallbackLegal(callback, origin); | ||
if (type === 'binding') { | ||
const userId = await this.getBindingUserIdFromCookie(ctx); | ||
if (!userId) { | ||
return this.illegalToBindAccount(ctx); | ||
} | ||
const state = this.formatState({ origin, userId, callback }); | ||
const url = await this.miniprogramAuthenticator.authorizeURL(origin + this.miniprogramBindUri, state, this.miniprogramPrompt); | ||
return ctx.redirect(url); | ||
} | ||
const state = this.formatState({ origin, callback }); | ||
const url = await this.miniprogramAuthenticator.authorizeURL(origin + this.miniprogramTokenUri, state, this.miniprogramPrompt); | ||
ctx.redirect(url); | ||
}; | ||
this.redirectMoziToken = async (ctx) => { | ||
const { code, state } = ctx.request.query; | ||
const { origin, callback } = this.parseState(state); | ||
const authenticationInformation = await this.moziAuthenticator.authenticate(code, origin + this.moziTokenUri); | ||
await this.handleAuthenticationInformation(ctx, authenticationInformation, callback); | ||
}; | ||
this.redirectGoogleToken = async (ctx) => { | ||
const { code, state } = ctx.request.query; | ||
const { origin, callback } = this.parseState(state); | ||
const authenticationInformation = await this.googleAuthenticator.authenticate(code, origin + this.googleTokenUri); | ||
await this.handleAuthenticationInformation(ctx, authenticationInformation, callback); | ||
}; | ||
this.redirectMiniprogramToken = async (ctx) => { | ||
const { loginToken, state } = ctx.request.query; | ||
const { origin, callback } = this.parseState(state); | ||
const authenticationInformation = await this.miniprogramAuthenticator.authenticate(loginToken, origin + this.miniprogramTokenUri); | ||
await this.handleAuthenticationInformation(ctx, authenticationInformation, callback); | ||
}; | ||
this.bindMozi = async (ctx) => { | ||
const { code, state } = ctx.query; | ||
const { origin, userId, callback } = this.parseState(state); | ||
await this.moziAuthenticator.bind(userId, code, origin + this.moziBindUri); | ||
ctx.redirect(callback); | ||
}; | ||
this.bindGoogle = async (ctx) => { | ||
const { code, state } = ctx.query; | ||
const { origin, userId, callback } = this.parseState(state); | ||
await this.googleAuthenticator.bind(userId, code, origin + this.googleBindUri); | ||
ctx.redirect(callback); | ||
}; | ||
this.bindMiniprogram = async (ctx) => { | ||
const { loginToken, state } = ctx.query; | ||
const { origin, userId, callback } = this.parseState(state); | ||
await this.miniprogramAuthenticator.bind(userId, loginToken, origin + this.miniprogramBindUri); | ||
ctx.redirect(callback); | ||
}; | ||
this.fallback = async (ctx, next) => { | ||
// verify | ||
const token = ctx.cookies.get('Authorization'); | ||
let sub; | ||
if (this.authHandler) { | ||
sub = await this.subjectProvider.verify(token); | ||
if (!sub) { | ||
const redirectIgnored = this.unauthorizedRedirectIgnore && ctx.request.path.startsWith(this.unauthorizedRedirectIgnore); | ||
if (this.unautorizedRedirectUri && !redirectIgnored) { | ||
const callback = encodeURIComponent(ctx.request.path + ctx.request.search); | ||
return ctx.redirect(`${this.unautorizedRedirectUri}?callback=${callback}`); | ||
} | ||
ctx.status = 401; | ||
return; | ||
} | ||
await this.authHandler(ctx, sub); | ||
const refreshedToken = this.subjectProvider.refresh(token); | ||
if (refreshedToken) { | ||
this.saveJsonWebTokenToHeader(ctx, refreshedToken); | ||
} | ||
} | ||
else { | ||
const authenticationInformation = await this.jwtProvider.verify(token); | ||
if (!authenticationInformation) { | ||
const redirectIgnored = this.unauthorizedRedirectIgnore && ctx.request.path.startsWith(this.unauthorizedRedirectIgnore); | ||
if (this.unautorizedRedirectUri && !redirectIgnored) { | ||
const callback = encodeURIComponent(ctx.request.path + ctx.request.search); | ||
return ctx.redirect(`${this.unautorizedRedirectUri}?callback=${callback}`); | ||
} | ||
ctx.status = 401; | ||
return; | ||
} | ||
sub = authenticationInformation.primaryPrincipal.id; | ||
this.saveAuthenticationInformationToContext(ctx, authenticationInformation); | ||
const refreshedToken = this.jwtProvider.refresh(token); | ||
if (refreshedToken) { | ||
this.saveJsonWebTokenToHeader(ctx, refreshedToken); | ||
} | ||
} | ||
if (this.permissionHandler) { | ||
await this.permissionHandler(ctx, sub); | ||
} | ||
return next(); | ||
}; | ||
this.handleAuthenticationInformation = async (ctx, authenticationInformation, callback) => { | ||
this.saveAuthenticationInformationToContext(ctx, authenticationInformation); | ||
const token = this.jwtProvider.authenticate(authenticationInformation); | ||
this.saveJsonWebTokenToHeader(ctx, token); | ||
if (this.loginHandler) { | ||
await this.loginHandler(ctx, authenticationInformation); | ||
} | ||
ctx.redirect(callback); | ||
}; | ||
this.saveAuthenticationInformationToContext = (ctx, authenticationInformation) => { | ||
ctx.authenticationInformation = authenticationInformation; | ||
}; | ||
this.saveJsonWebTokenToHeader = (ctx, token) => { | ||
ctx.cookies.set('Authorization', token, { | ||
path: '/', | ||
httpOnly: true, | ||
maxAge: this.maxAge, | ||
}); | ||
}; | ||
this.formatState = (obj = {}) => { | ||
return Buffer.from(JSON.stringify(obj)).toString('base64'); | ||
}; | ||
this.parseState = (str = '') => { | ||
return JSON.parse(Buffer.from(str, 'base64').toString('utf8')); | ||
}; | ||
const kflowApi = new kauth_sdk_node_1.KflowApi(kauthConfig); | ||
@@ -198,2 +52,4 @@ const kauthApi = new kauth_sdk_node_1.KauthApi(kauthConfig); | ||
this.unauthorizedRedirectIgnore = kauthConfig.unauthorizedRedirectIgnore; | ||
this.cookieDomain = kauthConfig.cookieDomain; | ||
this.callbackWhitelist = kauthConfig.callbackWhitelist; | ||
this.loginHandler = kauthConfig.loginHandler; | ||
@@ -221,2 +77,146 @@ this.authHandler = kauthConfig.authHandler; | ||
} | ||
dispatch = async (ctx, next) => { | ||
await this.router.dispatch(ctx, next); | ||
}; | ||
logout = async (ctx) => { | ||
const { callback } = ctx.request.query; | ||
ctx.cookies.set('Authorization', '', { | ||
path: '/', | ||
httpOnly: true, | ||
maxAge: 0, | ||
}); | ||
if (callback) { | ||
ctx.redirect(callback); | ||
return; | ||
} | ||
ctx.redirect(this.logoutRedirectUri); | ||
}; | ||
redirectMoziAuthorizeUri = async (ctx) => { | ||
const { type, origin, callback = origin } = ctx.request.query; | ||
this.assertCallbackWhitelist(callback); | ||
if (type === 'binding') { | ||
const userId = await this.getBindingUserIdFromCookie(ctx); | ||
if (!userId) { | ||
return this.illegalToBindAccount(ctx); | ||
} | ||
const state = this.formatState({ origin, userId, callback }); | ||
const url = await this.moziAuthenticator.authorizeURL(origin + this.moziBindUri, state, this.moziPrompt); | ||
return ctx.redirect(url); | ||
} | ||
const state = this.formatState({ origin, callback }); | ||
const url = await this.moziAuthenticator.authorizeURL(origin + this.moziTokenUri, state, this.moziPrompt); | ||
ctx.redirect(url); | ||
}; | ||
redirectGoogleAuthorizeUri = async (ctx) => { | ||
const { type, origin, callback = origin } = ctx.request.query; | ||
this.assertCallbackWhitelist(callback); | ||
if (type === 'binding') { | ||
const userId = await this.getBindingUserIdFromCookie(ctx); | ||
if (!userId) { | ||
return this.illegalToBindAccount(ctx); | ||
} | ||
const state = this.formatState({ origin, userId, callback }); | ||
const url = await this.googleAuthenticator.authorizeURL(origin + this.googleBindUri, state, this.googlePrompt); | ||
return ctx.redirect(url); | ||
} | ||
const state = this.formatState({ origin, callback }); | ||
const url = await this.googleAuthenticator.authorizeURL(origin + this.googleTokenUri, state, this.googlePrompt); | ||
ctx.redirect(url); | ||
}; | ||
redirectMiniProgarmAuthorizeUri = async (ctx) => { | ||
const { type, origin, callback = origin } = ctx.request.query; | ||
this.assertCallbackWhitelist(callback); | ||
if (type === 'binding') { | ||
const userId = await this.getBindingUserIdFromCookie(ctx); | ||
if (!userId) { | ||
return this.illegalToBindAccount(ctx); | ||
} | ||
const state = this.formatState({ origin, userId, callback }); | ||
const url = await this.miniprogramAuthenticator.authorizeURL(origin + this.miniprogramBindUri, state, this.miniprogramPrompt); | ||
return ctx.redirect(url); | ||
} | ||
const state = this.formatState({ origin, callback }); | ||
const url = await this.miniprogramAuthenticator.authorizeURL(origin + this.miniprogramTokenUri, state, this.miniprogramPrompt); | ||
ctx.redirect(url); | ||
}; | ||
redirectMoziToken = async (ctx) => { | ||
const { code, state } = ctx.request.query; | ||
const { origin, callback } = this.parseState(state); | ||
const authenticationInformation = await this.moziAuthenticator.authenticate(code, origin + this.moziTokenUri); | ||
await this.handleAuthenticationInformation(ctx, authenticationInformation, callback); | ||
}; | ||
redirectGoogleToken = async (ctx) => { | ||
const { code, state } = ctx.request.query; | ||
const { origin, callback } = this.parseState(state); | ||
const authenticationInformation = await this.googleAuthenticator.authenticate(code, origin + this.googleTokenUri); | ||
await this.handleAuthenticationInformation(ctx, authenticationInformation, callback); | ||
}; | ||
redirectMiniprogramToken = async (ctx) => { | ||
const { loginToken, state } = ctx.request.query; | ||
const { origin, callback } = this.parseState(state); | ||
const authenticationInformation = await this.miniprogramAuthenticator.authenticate(loginToken, origin + this.miniprogramTokenUri); | ||
await this.handleAuthenticationInformation(ctx, authenticationInformation, callback); | ||
}; | ||
bindMozi = async (ctx) => { | ||
const { code, state } = ctx.query; | ||
const { origin, userId, callback } = this.parseState(state); | ||
await this.moziAuthenticator.bind(userId, code, origin + this.moziBindUri); | ||
ctx.redirect(callback); | ||
}; | ||
bindGoogle = async (ctx) => { | ||
const { code, state } = ctx.query; | ||
const { origin, userId, callback } = this.parseState(state); | ||
await this.googleAuthenticator.bind(userId, code, origin + this.googleBindUri); | ||
ctx.redirect(callback); | ||
}; | ||
bindMiniprogram = async (ctx) => { | ||
const { loginToken, state } = ctx.query; | ||
const { origin, userId, callback } = this.parseState(state); | ||
await this.miniprogramAuthenticator.bind(userId, loginToken, origin + this.miniprogramBindUri); | ||
ctx.redirect(callback); | ||
}; | ||
fallback = async (ctx, next) => { | ||
// verify | ||
const token = ctx.cookies.get('Authorization'); | ||
let sub; | ||
if (this.authHandler) { | ||
sub = await this.subjectProvider.verify(token); | ||
if (!sub) { | ||
const redirectIgnored = this.unauthorizedRedirectIgnore && ctx.request.path.startsWith(this.unauthorizedRedirectIgnore); | ||
if (this.unautorizedRedirectUri && !redirectIgnored) { | ||
const callback = encodeURIComponent(ctx.request.path + ctx.request.search); | ||
return ctx.redirect(`${this.unautorizedRedirectUri}?callback=${callback}`); | ||
} | ||
ctx.status = 401; | ||
return; | ||
} | ||
await this.authHandler(ctx, sub); | ||
const refreshedToken = this.subjectProvider.refresh(token); | ||
if (refreshedToken) { | ||
this.saveJsonWebTokenToHeader(ctx, refreshedToken); | ||
} | ||
} | ||
else { | ||
const authenticationInformation = await this.jwtProvider.verify(token); | ||
if (!authenticationInformation) { | ||
const redirectIgnored = this.unauthorizedRedirectIgnore && ctx.request.path.startsWith(this.unauthorizedRedirectIgnore); | ||
if (this.unautorizedRedirectUri && !redirectIgnored) { | ||
const callback = encodeURIComponent(ctx.request.path + ctx.request.search); | ||
return ctx.redirect(`${this.unautorizedRedirectUri}?callback=${callback}`); | ||
} | ||
ctx.status = 401; | ||
return; | ||
} | ||
sub = authenticationInformation.primaryPrincipal.id; | ||
this.saveAuthenticationInformationToContext(ctx, authenticationInformation); | ||
const refreshedToken = this.jwtProvider.refresh(token); | ||
if (refreshedToken) { | ||
this.saveJsonWebTokenToHeader(ctx, refreshedToken); | ||
} | ||
} | ||
if (this.permissionHandler) { | ||
await this.permissionHandler(ctx, sub); | ||
} | ||
return next(); | ||
}; | ||
illegalToBindAccount(ctx) { | ||
@@ -233,12 +233,44 @@ ctx.status = 500; | ||
} | ||
assertCallbackLegal(callback, origin) { | ||
const { host: callbackHost } = new url_1.URL(callback); | ||
const { host: originHost } = new url_1.URL(origin); | ||
if (callbackHost !== originHost) { | ||
throw new Error('callback host not match origin host'); | ||
handleAuthenticationInformation = async (ctx, authenticationInformation, callback) => { | ||
this.saveAuthenticationInformationToContext(ctx, authenticationInformation); | ||
const token = this.jwtProvider.authenticate(authenticationInformation); | ||
this.saveJsonWebTokenToHeader(ctx, token); | ||
if (this.loginHandler) { | ||
await this.loginHandler(ctx, authenticationInformation); | ||
} | ||
ctx.redirect(callback); | ||
}; | ||
saveAuthenticationInformationToContext = (ctx, authenticationInformation) => { | ||
ctx.authenticationInformation = authenticationInformation; | ||
}; | ||
saveJsonWebTokenToHeader = (ctx, token) => { | ||
ctx.cookies.set('Authorization', token, { | ||
path: '/', | ||
httpOnly: true, | ||
maxAge: this.maxAge, | ||
domain: this.cookieDomain || undefined, | ||
}); | ||
}; | ||
assertCallbackWhitelist(url) { | ||
const callback = new url_1.URL(url); | ||
if (this.callbackWhitelist && !this.callbackWhitelist.includes(callback.hostname)) { | ||
throw new Error(`${callback.hostname} is't in whitelist`); | ||
} | ||
} | ||
formatState = (obj = {}) => { | ||
return Buffer.from(JSON.stringify(obj)).toString('base64'); | ||
}; | ||
parseState = (str = '') => { | ||
return JSON.parse(Buffer.from(str, 'base64').toString('utf8')); | ||
}; | ||
} | ||
exports.KauthProvider = KauthProvider; | ||
class KauthRouter { | ||
_kauthApi; | ||
_kflowApi; | ||
_tracerInjected; | ||
_traceConsumerKey; | ||
_traceConsumer; | ||
_routes; | ||
_fallback; | ||
constructor(kauthApi, kflowApi, tracerInjected, traceConsumerKey, traceConsumer) { | ||
@@ -245,0 +277,0 @@ this._routes = {}; |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
@@ -10,5 +14,5 @@ if (k2 === undefined) k2 = k; | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p); | ||
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__exportStar(require("kauth-sdk-node"), exports); |
{ | ||
"name": "egg-kauth", | ||
"version": "2.0.8", | ||
"version": "2.0.13-alpha.0", | ||
"description": "egg kauth plugin", | ||
@@ -28,9 +28,10 @@ "eggPlugin": { | ||
"dependencies": { | ||
"kauth-sdk-node": "^2.0.12" | ||
"kauth-sdk-node": "^2.0.13-alpha.0" | ||
}, | ||
"devDependencies": { | ||
"@types/mocha": "^8.0.0", | ||
"@types/mocha": "^10.0.1", | ||
"@types/node": "^16.18.70", | ||
"@types/sinon": "^9.0.4", | ||
"@typescript-eslint/eslint-plugin": "^3.7.1", | ||
"@typescript-eslint/parser": "^3.7.1", | ||
"@typescript-eslint/eslint-plugin": "^6.18.1", | ||
"@typescript-eslint/parser": "^6.18.1", | ||
"conventional-changelog-cli": "^2.1.0", | ||
@@ -40,16 +41,16 @@ "egg": "^2.27.0", | ||
"egg-mock": "^4.2.1", | ||
"eslint": "^7.5.0", | ||
"eslint-config-prettier": "^7.1.0", | ||
"eslint-plugin-prettier": "^3.3.1", | ||
"eslint": "^8.56.0", | ||
"eslint-config-prettier": "^9.1.0", | ||
"eslint-plugin-prettier": "^5.1.3", | ||
"husky": "^4.3.7", | ||
"lint-staged": "^10.5.3", | ||
"mocha": "^8.0.1", | ||
"mocha": "^5.2.0", | ||
"mocha-junit-reporter": "^2.0.2", | ||
"mocha-multi": "^1.1.6", | ||
"mocha-multi": "^1.1.7", | ||
"nyc": "^15.1.0", | ||
"prettier": "^2.2.1", | ||
"prettier": "^3.1.1", | ||
"rimraf": "^3.0.2", | ||
"sinon": "^9.0.2", | ||
"ts-node": "^10.9.1", | ||
"typescript": "^3.9.7" | ||
"typescript": "^5.3.3" | ||
}, | ||
@@ -66,3 +67,4 @@ "husky": { | ||
] | ||
} | ||
}, | ||
"repository": "git@code.alipay.com:marmot/kauth-sdk-egg.git" | ||
} |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
26167
597
23
2
+ Addedkauth-sdk-node@2.0.13-alpha.2(transitive)
- Removedkauth-sdk-node@2.0.12(transitive)