@lanaqi/rsr
Version:
1,427 lines • 64.6 kB
JavaScript
import * as __WEBPACK_EXTERNAL_MODULE_react_router_dom_5358f3fe__ from "react-router-dom";
import * as __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__ from "react/jsx-runtime";
import * as __WEBPACK_EXTERNAL_MODULE_react__ from "react";
var common_AccessDecision = /*#__PURE__*/ function(AccessDecision) {
AccessDecision["notResource"] = "notResource";
AccessDecision["notAuthentication"] = "notAuthentication";
AccessDecision["invalidAuthentication"] = "invalidAuthentication";
AccessDecision["notAuthorization"] = "notAuthorization";
AccessDecision["notSignature"] = "notSignature";
AccessDecision["accessDenied"] = "accessDenied";
AccessDecision["allowAccess"] = "allowAccess";
return AccessDecision;
}({});
var common_AccessBehave = /*#__PURE__*/ function(AccessBehave) {
AccessBehave["doNothing"] = "doNothing";
AccessBehave["goNavigate"] = "goNavigate";
AccessBehave["reDecision"] = "reDecision";
return AccessBehave;
}({});
class SimpleAuthentication {
datasheet;
authenticated;
constructor(datasheet){
this.datasheet = datasheet;
this.authenticated = this.datasheet.authenticated ?? false;
}
isAuthenticated() {
return this.authenticated;
}
setAuthenticated(authenticated) {
this.authenticated = authenticated;
}
getDatasheet() {
return this.datasheet;
}
}
class SimpleAuthorization {
datasheet;
permissions;
constructor(datasheet){
this.datasheet = datasheet;
this.permissions = new Set(this.datasheet.permissions);
}
getPermissions() {
return this.permissions;
}
getDatasheet() {
return this.datasheet;
}
}
class SimpleUser {
datasheet;
permissions;
authenticated;
invalid;
constructor(datasheet){
this.datasheet = datasheet;
this.permissions = new Set(this.datasheet.permissions);
this.authenticated = this.datasheet.authenticated ?? false;
this.invalid = this.datasheet.invalid ?? false;
}
isAuthenticated() {
return this.authenticated;
}
setAuthenticated(authenticated) {
this.authenticated = authenticated;
}
getPermissions() {
return this.permissions;
}
getDatasheet() {
return this.datasheet;
}
isInvalid() {
return this.invalid;
}
setInvalid(invalid) {
this.invalid = invalid;
}
}
class SimpleResource {
static PERMISSION_ANONYMOUS = '__anonymous__';
static PERMISSION_AUTHENTICATED = '__authenticated__';
static PERMISSION_AUTHORIZED = '__authorized__';
static LABEL_SIGNATURED = '__signatured__';
static LABEL_ALWAYS_SIGNATURE = '__always_signature__';
patterns;
permissions;
labels;
anonymous;
authenticated;
authorized;
signatured;
alwaysSignature;
basename;
constructor(patterns, permissions, labels, basename){
this.patterns = new Set(patterns);
this.permissions = new Set(permissions);
this.labels = new Set(labels);
if (0 === this.patterns.size) throw new Error("\u8BBF\u95EE\u8D44\u6E90\u6A21\u5F0F\u96C6\u5408\u4E0D\u80FD\u4E3A\u7A7A\uFF0C\u8BF7\u68C0\u67E5\uFF01");
if (0 === this.permissions.size) {
this.anonymous = true;
this.authenticated = false;
this.authorized = false;
} else {
if (this.permissions.has(SimpleResource.PERMISSION_ANONYMOUS)) {
this.permissions.clear();
this.anonymous = true;
} else this.anonymous = false;
if (this.permissions.has(SimpleResource.PERMISSION_AUTHENTICATED)) {
this.permissions.clear();
this.authenticated = true;
} else this.authenticated = false;
if (this.permissions.has(SimpleResource.PERMISSION_AUTHORIZED)) {
this.permissions.clear();
this.authorized = true;
} else this.authorized = false;
}
if (0 === this.labels.size) {
this.signatured = false;
this.alwaysSignature = false;
} else {
if (this.labels.has(SimpleResource.LABEL_SIGNATURED)) {
this.labels.delete(SimpleResource.LABEL_SIGNATURED);
this.signatured = true;
} else this.signatured = false;
if (this.labels.has(SimpleResource.LABEL_ALWAYS_SIGNATURE)) {
this.labels.delete(SimpleResource.LABEL_ALWAYS_SIGNATURE);
this.signatured = true;
this.alwaysSignature = true;
} else this.alwaysSignature = false;
}
this.basename = basename;
}
getPatterns() {
return this.patterns;
}
getPermissions() {
return this.permissions;
}
getLabels() {
return this.labels;
}
hasPattern(pattern) {
return this.patterns.has(pattern);
}
hasPermission(permission) {
return this.permissions.has(permission);
}
hasLabel(label) {
return this.labels.has(label);
}
isAnonymous() {
return this.anonymous;
}
isAuthenticated() {
return this.authenticated;
}
isAuthorized() {
return this.authorized;
}
isSignatured() {
return this.signatured;
}
isAlwaysSignature() {
return this.alwaysSignature;
}
getBasename() {
return this.basename;
}
setBasename(basename) {
this.basename = basename;
}
}
class SimpleRecorder {
currentPath;
allowPath;
originPath;
accessResource;
accessAuthentication;
accessAuthorization;
getCurrentPath() {
return this.currentPath;
}
setCurrentPath(currentPath) {
this.currentPath = currentPath;
}
existCurrentPath() {
return !!this.currentPath;
}
isCurrentPath(pathname) {
if (this.currentPath) return this.currentPath.pathname === pathname;
return false;
}
isCurrentPaths(...pathnames) {
for (const pathname of pathnames){
const yes = this.isCurrentPath(pathname);
if (yes) return true;
}
return false;
}
getAllowPath() {
return this.allowPath;
}
setAllowPath(allowPath) {
this.allowPath = allowPath;
}
existAllowPath() {
return !!this.allowPath;
}
isAllowPath(pathname) {
if (this.allowPath) return this.allowPath.pathname === pathname;
return false;
}
isAllowPaths(...pathnames) {
for (const pathname of pathnames){
const yes = this.isAllowPath(pathname);
if (yes) return true;
}
return false;
}
getOriginPath() {
return this.originPath;
}
setOriginPath(originPath) {
this.originPath = originPath;
}
existOriginPath() {
return !!this.originPath;
}
isOriginPath(pathname) {
if (this.originPath) return this.originPath.pathname === pathname;
return false;
}
isOriginPaths(...pathnames) {
for (const pathname of pathnames){
const yes = this.isOriginPath(pathname);
if (yes) return true;
}
return false;
}
getAccessResource() {
return this.accessResource;
}
setAccessResource(accessResource) {
this.accessResource = accessResource;
}
existAccessResource() {
return !!this.accessResource;
}
getAccessAuthentication() {
return this.accessAuthentication;
}
setAccessAuthentication(accessAuthentication) {
this.accessAuthentication = accessAuthentication;
}
existAccessAuthentication() {
return !!this.accessAuthentication;
}
getAccessAuthorization() {
return this.accessAuthorization;
}
setAccessAuthorization(accessAuthorization) {
this.accessAuthorization = accessAuthorization;
}
existAccessAuthorization() {
return !!this.accessAuthorization;
}
clearOriginPath() {
this.originPath = void 0;
}
clearAccessResource() {
this.accessResource = void 0;
}
clearAccessAuthentication() {
this.accessAuthentication = void 0;
}
clearAccessAuthorization() {
this.accessAuthorization = void 0;
}
}
class CacheVoter {
cache;
constructor(){
this.cache = new Map();
}
cacheKey(term, have) {
return `${[
...have
].join('.')}_${[
...term
].join('.')}`;
}
clearCache() {
this.cache.clear();
}
vote(term, have) {
if (0 === term.size || 0 === have.size) return false;
const key = this.cacheKey(term, have);
if (this.cache.has(key)) return this.cache.get(key);
const result = this.execVote(term, have);
this.cache.set(key, result);
return result;
}
}
class SimpleVoter extends CacheVoter {
all;
constructor(all = false){
super();
this.all = all;
}
setAll(all) {
this.all = all;
}
execVote(term, have) {
for (const item of term)if (this.all) {
if (!have.has(item)) return false;
} else if (have.has(item)) return true;
return this.all;
}
}
class HierarchyPermission {
permission;
parent;
constructor(permission){
this.permission = permission;
}
getPermission() {
return this.permission;
}
setParent(parent) {
this.parent = parent;
}
getParent() {
return this.parent;
}
includeMy(permission) {
if (this.permission === permission) return true;
if (this.parent) return this.parent.includeMy(permission);
return false;
}
}
const OriginRelationResolver = (relation)=>relation;
class HierarchyVoter extends CacheVoter {
mapping;
relation;
all;
resolver;
constructor(resolver, relation, all = false){
super();
this.mapping = new Map();
this.relation = relation;
this.all = all;
this.resetResolver(resolver);
}
setAll(all) {
this.all = all;
}
resetRelation(relation) {
this.relation = relation;
this.initHierarchy();
}
resetResolver(resolver) {
this.resolver = resolver;
this.initHierarchy();
}
initHierarchy() {
const hierarchy = this.resolver(this.relation);
const group = hierarchy.split(';');
if (group.length > 0) {
this.clearCache();
this.mapping.clear();
for (const item of group){
const ps = item.split('>');
if (2 === ps.length) {
const p1 = ps[0];
const p2 = ps[1];
let h1;
if (this.mapping.has(p1)) h1 = this.mapping.get(p1);
else {
h1 = new HierarchyPermission(p1);
this.mapping.set(p1, h1);
}
let h2;
if (this.mapping.has(p2)) h2 = this.mapping.get(p2);
else {
h2 = new HierarchyPermission(p2);
this.mapping.set(p2, h2);
}
h2.setParent(h1);
}
}
}
}
includePermission(p1, p2) {
if (this.mapping.has(p2)) return this.mapping.get(p2).includeMy(p1);
return p1 === p2;
}
execVote(term, have) {
for (const tp of term)for (const hp of have){
const hi = this.includePermission(hp, tp);
if (hi) {
if (!this.all) return true;
} else if (this.all) return false;
}
return this.all;
}
getRelation() {
return this.relation;
}
}
class SimpleStorer {
static KEY_AUTHENTICATION = '__authentication__';
static KEY_AUTHORIZATION = '__authorization__';
static KEY_SIGNATURE = '__signature__';
aaaStorage;
signStorage;
authenticationKey;
authorizationKey;
signatureKey;
authenticationValidator;
constructor(aaaStorage, signStorage, authenticationKey = SimpleStorer.KEY_AUTHENTICATION, authorizationKey = SimpleStorer.KEY_AUTHORIZATION, signatureKey = SimpleStorer.KEY_SIGNATURE, authenticationValidator){
this.aaaStorage = aaaStorage;
this.signStorage = signStorage;
this.authenticationKey = authenticationKey;
this.authorizationKey = authorizationKey;
this.signatureKey = signatureKey;
this.authenticationValidator = authenticationValidator;
}
loadAuthentication(recorder) {
const authenticationStr = this.aaaStorage.getItem(this.authenticationKey);
if (authenticationStr) {
const authenticationObj = JSON.parse(authenticationStr);
if ('boolean' == typeof authenticationObj.authenticated) if (void 0 !== authenticationObj.permissions && Array.isArray(authenticationObj.permissions)) return new SimpleUser(authenticationObj);
else return new SimpleAuthentication(authenticationObj);
}
}
verifyAuthentication(recorder, authentication) {
if (this.authenticationValidator) return this.authenticationValidator(recorder, authentication);
return true;
}
deleteAuthentication(recorder) {
this.aaaStorage.removeItem(this.authenticationKey);
}
saveAuthentication(recorder, datasheet) {
const ds = datasheet.getDatasheet();
const authenticationStr = JSON.stringify(ds);
this.aaaStorage.setItem(this.authenticationKey, authenticationStr);
}
loadAuthorization(recorder, authentication) {
if (authentication && authentication instanceof SimpleUser) return authentication;
const authorizationStr = this.aaaStorage.getItem(this.authorizationKey);
if (authorizationStr) {
const authorizationObj = JSON.parse(authorizationStr);
if (void 0 !== authorizationObj.permissions && Array.isArray(authorizationObj.permissions)) return new SimpleAuthorization(authorizationObj);
}
}
deleteAuthorization(recorder) {
const authentication = recorder.getAccessAuthentication();
if (authentication && authentication instanceof SimpleUser) return;
this.aaaStorage.removeItem(this.authorizationKey);
}
saveAuthorization(recorder, datasheet) {
const authentication = recorder.getAccessAuthentication();
if (authentication && authentication instanceof SimpleUser) return;
const ds = datasheet.getDatasheet();
const authorizationStr = JSON.stringify(ds);
this.aaaStorage.setItem(this.authorizationKey, authorizationStr);
}
loadSignature(recorder, path, authentication, authorization) {
const signatureStr = this.signStorage.getItem(this.signatureKey);
if (signatureStr) {
const signatureList = JSON.parse(signatureStr);
if (Array.isArray(signatureList) && signatureList.includes(path.pathname)) return true;
}
return false;
}
removeSignature(recorder, path) {
const signatureStr = this.signStorage.getItem(this.signatureKey);
if (signatureStr) {
const signatureList = JSON.parse(signatureStr);
if (Array.isArray(signatureList)) {
const newSignatureList = signatureList.filter((signature)=>signature !== path.pathname);
const newSignatureStr = JSON.stringify(newSignatureList);
this.signStorage.setItem(this.signatureKey, newSignatureStr);
}
}
}
deleteSignature(recorder) {
this.signStorage.removeItem(this.signatureKey);
}
saveSignature(recorder, path) {
let signatureList;
const signatureStr = this.signStorage.getItem(this.signatureKey);
if (signatureStr) {
signatureList = JSON.parse(signatureStr);
if (!Array.isArray(signatureList)) signatureList = [];
} else signatureList = [];
const signatureSet = new Set(signatureList);
signatureSet.add(path.pathname);
const signatures = Array.from(signatureSet);
const newSignatureStr = JSON.stringify(signatures);
this.signStorage.setItem(this.signatureKey, newSignatureStr);
}
}
class SimpleMatcher {
cache;
resources;
basename;
constructor(resources){
this.cache = new Map();
this.resources = resources;
}
match(resource, path) {
let basename = resource.getBasename();
if (!basename) basename = this.getBasename();
const patterns = resource.getPatterns();
if (basename && basename.trim().length > 0) for (const pattern of patterns){
let matchPattern;
matchPattern = 'string' == typeof pattern ? basename + pattern : {
...pattern,
path: basename + pattern.path
};
const pm = (0, __WEBPACK_EXTERNAL_MODULE_react_router_dom_5358f3fe__.matchPath)(matchPattern, path.pathname);
if (pm) return true;
}
else for (const pattern of patterns){
const pm = (0, __WEBPACK_EXTERNAL_MODULE_react_router_dom_5358f3fe__.matchPath)(pattern, path.pathname);
if (pm) return true;
}
return false;
}
obtain(path) {
const pathname = path.pathname;
if (this.cache.has(pathname)) return this.cache.get(pathname);
for (const resource of this.resources){
const mp = this.match(resource, path);
if (mp) {
this.cache.set(pathname, resource);
return resource;
}
}
return null;
}
getBasename() {
return this.basename;
}
setBasename(basename) {
this.basename = basename;
}
}
class SimpleNavigator {
_navigate;
constructor(navigate){
this._navigate = navigate;
}
navigate(to, options) {
this._navigate(to, options);
}
}
class SimpleContext {
recorder;
voter;
storer;
matcher;
navigator;
parent;
constructor(recorder, voter, storer, matcher, navigator){
this.recorder = recorder;
this.voter = voter;
this.storer = storer;
this.matcher = matcher;
this.navigator = navigator;
}
getRecorder() {
return this.recorder;
}
setRecorder(recorder) {
this.recorder = recorder;
}
getVoter() {
return this.voter;
}
setVoter(voter) {
this.voter = voter;
}
getStorer() {
return this.storer;
}
setStorer(storer) {
this.storer = storer;
}
getMatcher() {
return this.matcher;
}
setMatcher(matcher) {
this.matcher = matcher;
}
getNavigator() {
return this.navigator;
}
setNavigator(navigator) {
this.navigator = navigator;
}
getParent() {
return this.parent;
}
setParent(parent) {
this.parent = parent;
}
}
class AbstractAddon {
guardBefore(context, manager, currentPath, currentResource) {}
guardAfter(context, manager, currentPath, currentResource, currentDecision) {}
permitBefore(context, manager, stayPath, blockPath, stayResource, blockResource) {}
permitAfter(context, manager, stayPath, blockPath, stayResource, blockResource) {}
}
class BehaveHandler {
_config;
constructor(config){
this._config = config;
}
config(config) {
this._config = config;
}
notResource(context) {
if (this._config.notResourcePath) {
context.getNavigator().navigate(this._config.notResourcePath);
return common_AccessBehave.goNavigate;
}
if (this._config.notResourceFunc) return this._config.notResourceFunc(context);
return this.accessDenied(context);
}
notAuthentication(context) {
if (this._config.notAuthenticationPath) {
context.getNavigator().navigate(this._config.notAuthenticationPath);
return common_AccessBehave.goNavigate;
}
if (this._config.notAuthenticationFunc) return this._config.notAuthenticationFunc(context);
throw new Error("\u6CA1\u6709\u8BA4\u8BC1\u7684\u884C\u4E3A\u662F\u5FC5\u987B\u914D\u7F6E\u7684\uFF0C\u8BF7\u68C0\u67E5\uFF01");
}
invalidAuthentication(context) {
if (this._config.invalidAuthenticationPath) {
context.getNavigator().navigate(this._config.invalidAuthenticationPath);
return common_AccessBehave.goNavigate;
}
if (this._config.invalidAuthenticationFunc) return this._config.invalidAuthenticationFunc(context);
return this.notAuthentication(context);
}
notAuthorization(context) {
if (this._config.notAuthorizationPath) {
context.getNavigator().navigate(this._config.notAuthorizationPath);
return common_AccessBehave.goNavigate;
}
if (this._config.notAuthorizationFunc) return this._config.notAuthorizationFunc(context);
return this.accessDenied(context);
}
notSignature(context) {
if (this._config.notSignaturePath) {
context.getNavigator().navigate(this._config.notSignaturePath);
return common_AccessBehave.goNavigate;
}
if (this._config.notSignatureFunc) return this._config.notSignatureFunc(context);
return this.accessDenied(context);
}
accessDenied(context) {
if (this._config.accessDeniedPath) {
context.getNavigator().navigate(this._config.accessDeniedPath);
return common_AccessBehave.goNavigate;
}
if (this._config.accessDeniedFunc) return this._config.accessDeniedFunc(context);
throw new Error("\u62D2\u7EDD\u8BBF\u95EE\u7684\u884C\u4E3A\u662F\u5FC5\u987B\u914D\u7F6E\u7684\uFF0C\u8BF7\u68C0\u67E5\uFF01");
}
allowAccess(context) {
if (this._config.allowAccessFunc) this._config.allowAccessFunc(context);
return common_AccessBehave.doNothing;
}
errorDecision(context, decision) {
if (this._config.errorDecisionFunc) return void this._config.errorDecisionFunc(context, decision);
if (decision === common_AccessDecision.notSignature) return;
switch(decision){
case common_AccessDecision.notResource:
this.accessDenied(context);
break;
case common_AccessDecision.notAuthentication:
throw new Error("\u6CA1\u6709\u8BA4\u8BC1\u7684\u9519\u8BEF\u51B3\u7B56\uFF0C\u8BF7\u68C0\u67E5\uFF01");
case common_AccessDecision.invalidAuthentication:
this.notAuthentication(context);
break;
case common_AccessDecision.notAuthorization:
this.accessDenied(context);
break;
case common_AccessDecision.accessDenied:
default:
throw new Error("\u62D2\u7EDD\u8BBF\u95EE\u7684\u9519\u8BEF\u51B3\u7B56\uFF0C\u8BF7\u68C0\u67E5\uFF01");
}
}
}
class SingleBlocker {
handler;
block(context, currentPath, currentResource) {
if (this.handler) return this.handler(context, currentPath, currentResource);
return false;
}
register(handler) {
this.handler = handler;
}
unregister(handler) {
this.handler = void 0;
}
}
class MultiBlocker {
handlers;
constructor(){
this.handlers = new Set();
}
block(context, currentPath, currentResource) {
for (const handler of this.handlers){
const blocked = handler(context, currentPath, currentResource);
if (blocked) return true;
}
return false;
}
register(handler) {
this.handlers.add(handler);
}
unregister(handler) {
this.handlers.delete(handler);
}
clear() {
this.handlers.clear();
}
}
class SimpleManager {
disabled;
handler;
blocker;
parent;
constructor(disabled, handler, blocker){
this.disabled = disabled;
this.handler = handler;
this.blocker = blocker;
}
isDisabled() {
return this.disabled;
}
setDisabled(disabled) {
this.disabled = disabled;
}
getHandler() {
return this.handler;
}
setHandler(handler) {
this.handler = handler;
}
getBlocker() {
return this.blocker;
}
setBlocker(blocker) {
this.blocker = blocker;
}
getParent() {
return this.parent;
}
setParent(parent) {
this.parent = parent;
}
}
class SimpleGuarder {
context;
manager;
addons;
constructor(context, manager, addons){
this.context = context;
this.manager = manager;
this.addons = addons;
}
guardDecision(blockPath) {
const recorder = this.context.getRecorder();
recorder.setCurrentPath(blockPath);
const resource = this.obtainResource(blockPath);
let authentication;
if (recorder.existAccessAuthentication()) authentication = recorder.getAccessAuthentication();
else {
authentication = this.obtainAuthentication();
if (authentication) recorder.setAccessAuthentication(authentication);
}
let authorization;
if (recorder.existAccessAuthorization()) authorization = recorder.getAccessAuthorization();
else {
authorization = this.obtainAuthorization(authentication);
if (authorization) recorder.setAccessAuthorization(authorization);
}
if (resource) recorder.setAccessResource(resource);
else {
recorder.clearAccessResource();
return common_AccessDecision.notResource;
}
if (resource.isAnonymous()) {
recorder.setAllowPath(blockPath);
return common_AccessDecision.allowAccess;
}
if (authentication && authentication.isAuthenticated()) recorder.clearOriginPath();
else {
recorder.setOriginPath(blockPath);
return common_AccessDecision.notAuthentication;
}
const valid = this.checkAuthentication(authentication);
if (valid) recorder.clearOriginPath();
else {
recorder.setOriginPath(blockPath);
return common_AccessDecision.invalidAuthentication;
}
if (resource.isAuthenticated()) {
recorder.setAllowPath(blockPath);
return common_AccessDecision.allowAccess;
}
if (authorization) recorder.clearOriginPath();
else {
recorder.setOriginPath(blockPath);
return common_AccessDecision.notAuthorization;
}
if (resource.isAuthorized()) {
recorder.setAllowPath(blockPath);
return common_AccessDecision.allowAccess;
}
const authorized = this.checkPermission(resource, authorization);
if (authorized) recorder.clearOriginPath();
else {
recorder.setOriginPath(blockPath);
return common_AccessDecision.accessDenied;
}
if (resource.isSignatured() && !this.checkSignature(blockPath, authentication, authorization)) {
recorder.setOriginPath(blockPath);
return common_AccessDecision.notSignature;
}
recorder.clearOriginPath();
recorder.setAllowPath(blockPath);
return common_AccessDecision.allowAccess;
}
guardHandle(currentDecision, beforeDecision) {
const recorder = this.context.getRecorder();
const storer = this.context.getStorer();
const handler = this.manager.getHandler();
if (beforeDecision && beforeDecision !== common_AccessDecision.allowAccess && beforeDecision === currentDecision) {
if (beforeDecision === common_AccessDecision.invalidAuthentication) {
recorder.clearAccessAuthentication();
recorder.clearAccessAuthorization();
storer.deleteAuthentication(recorder);
storer.deleteAuthorization(recorder);
storer.deleteSignature(recorder);
}
handler.errorDecision(this.context, currentDecision);
return common_AccessBehave.doNothing;
}
let behave;
switch(currentDecision){
case common_AccessDecision.notResource:
behave = handler.notResource(this.context);
break;
case common_AccessDecision.notAuthentication:
recorder.clearAccessAuthentication();
recorder.clearAccessAuthorization();
storer.deleteAuthentication(recorder);
storer.deleteAuthorization(recorder);
storer.deleteSignature(recorder);
behave = handler.notAuthentication(this.context);
break;
case common_AccessDecision.invalidAuthentication:
behave = handler.invalidAuthentication(this.context);
break;
case common_AccessDecision.notAuthorization:
recorder.clearAccessAuthorization();
storer.deleteAuthorization(recorder);
storer.deleteSignature(recorder);
behave = handler.notAuthorization(this.context);
break;
case common_AccessDecision.notSignature:
behave = handler.notSignature(this.context);
break;
case common_AccessDecision.allowAccess:
behave = handler.allowAccess(this.context);
break;
case common_AccessDecision.accessDenied:
default:
behave = handler.accessDenied(this.context);
break;
}
return behave;
}
guardBlock(currentPath) {
const currentResource = this.obtainResource(currentPath);
const blocker = this.manager.getBlocker();
return blocker.block(this.context, currentPath, currentResource);
}
guardBefore(currentPath) {
const currentResource = this.obtainResource(currentPath);
this.forAddons((addon)=>{
addon.guardBefore(this.context, this.manager, currentPath, currentResource);
});
}
guardAfter(currentPath, currentDecision) {
const currentResource = this.obtainResource(currentPath);
this.forAddons((addon)=>{
addon.guardAfter(this.context, this.manager, currentPath, currentResource, currentDecision);
});
}
permitBefore(stayPath, blockPath) {
const stayResource = this.obtainResource(stayPath);
const blockResource = this.obtainResource(blockPath);
this.clearSignature(stayPath, stayResource);
this.forAddons((addon)=>{
addon.permitBefore(this.context, this.manager, stayPath, blockPath, stayResource, blockResource);
});
}
permitAfter(stayPath, blockPath) {
const stayResource = this.obtainResource(stayPath);
const blockResource = this.obtainResource(blockPath);
this.forAddons((addon)=>{
addon.permitAfter(this.context, this.manager, stayPath, blockPath, stayResource, blockResource);
});
}
forAddons(fn) {
if (Array.isArray(this.addons) && this.addons.length > 0) for (const addon of this.addons)fn(addon);
}
obtainResource(path) {
const matcher = this.context.getMatcher();
return matcher.obtain(path);
}
obtainAuthentication() {
const storer = this.context.getStorer();
const recorder = this.context.getRecorder();
return storer.loadAuthentication(recorder);
}
checkAuthentication(authentication) {
const storer = this.context.getStorer();
const recorder = this.context.getRecorder();
return storer.verifyAuthentication(recorder, authentication);
}
obtainAuthorization(authentication) {
const storer = this.context.getStorer();
const recorder = this.context.getRecorder();
return storer.loadAuthorization(recorder, authentication);
}
checkPermission(resource, authorization) {
const voter = this.context.getVoter();
return voter.vote(resource.getPermissions(), authorization.getPermissions());
}
checkSignature(path, authentication, authorization) {
const storer = this.context.getStorer();
const recorder = this.context.getRecorder();
return storer.loadSignature(recorder, path, authentication, authorization);
}
clearSignature(stayPath, stayResource) {
if (stayResource?.isSignatured() && stayResource.isAlwaysSignature()) {
const storer = this.context.getStorer();
const recorder = this.context.getRecorder();
storer.removeSignature(recorder, stayPath);
}
}
}
class AccessRecorderBuilder {
build() {
return new SimpleRecorder();
}
}
class AccessVoterBuilder {
_resolver;
_hierarchy;
_all = false;
resolver(resolver) {
this._resolver = resolver;
return this;
}
hierarchy(hierarchy) {
this._hierarchy = hierarchy;
return this;
}
all(all) {
this._all = all;
return this;
}
build() {
if (this._hierarchy && this._hierarchy.trim().length > 0) {
if (!this._resolver) this._resolver = OriginRelationResolver;
return new HierarchyVoter(this._resolver, this._hierarchy, this._all);
}
return new SimpleVoter(this._all);
}
}
class AccessStorerBuilder {
_aaaStorage;
_signStorage;
_authenticationKey;
_authorizationKey;
_signatureKey;
_authenticationValidator;
aaaStorage(aaaStorage) {
this._aaaStorage = aaaStorage;
return this;
}
signStorage(signStorage) {
this._signStorage = signStorage;
return this;
}
authenticationKey(authenticationKey) {
this._authenticationKey = authenticationKey;
return this;
}
authorizationKey(authorizationKey) {
this._authorizationKey = authorizationKey;
return this;
}
signatureKey(signatureKey) {
this._signatureKey = signatureKey;
return this;
}
authenticationValidator(authenticationValidator) {
this._authenticationValidator = authenticationValidator;
return this;
}
local() {
return this.aaaStorage(window.localStorage).signStorage(window.localStorage);
}
session() {
return this.aaaStorage(window.sessionStorage).signStorage(window.sessionStorage);
}
blend() {
return this.aaaStorage(window.localStorage).signStorage(window.sessionStorage);
}
build() {
if (!this._aaaStorage && !this._signStorage) this.session();
if (!this._aaaStorage) this.aaaStorage(window.localStorage);
if (!this._signStorage) this.signStorage(window.sessionStorage);
return new SimpleStorer(this._aaaStorage, this._signStorage, this._authenticationKey, this._authorizationKey, this._signatureKey, this._authenticationValidator);
}
}
class AccessResourceBuilder {
_patterns = new Set();
_permissions = new Set();
_labels = new Set();
_basename;
patterns(...patterns) {
for (const pattern of patterns)this._patterns.add(pattern);
return this;
}
permissions(...permissions) {
for (const permission of permissions)this._permissions.add(permission);
return this;
}
labels(...labels) {
for (const label of labels)this._labels.add(label);
return this;
}
anonymous() {
this._permissions.add(SimpleResource.PERMISSION_ANONYMOUS);
return this;
}
authenticated() {
this._permissions.add(SimpleResource.PERMISSION_AUTHENTICATED);
return this;
}
authorized() {
this._permissions.add(SimpleResource.PERMISSION_AUTHORIZED);
return this;
}
signatured() {
this._labels.add(SimpleResource.LABEL_SIGNATURED);
return this;
}
alwaysSignature() {
this.signatured();
this._labels.add(SimpleResource.LABEL_ALWAYS_SIGNATURE);
return this;
}
basename(basename) {
this._basename = basename;
return this;
}
config(config) {
this.patterns(...config.patterns).permissions(...config.permissions);
if (config.labels) this.labels(...config.labels);
if (config.basename) this.basename(config.basename);
return this;
}
build() {
return new SimpleResource(this._patterns, this._permissions, this._labels, this._basename);
}
}
class AccessMatcherBuilder {
_resources = [];
config(config) {
this._resources.push(new AccessResourceBuilder().config(config).build());
return this;
}
configs(...configs) {
for (const config of configs)this.config(config);
return this;
}
resource(builder) {
this._resources.push(builder(new AccessResourceBuilder()));
return this;
}
resources(resources) {
this._resources.push(...resources);
return this;
}
build() {
return new SimpleMatcher(this._resources);
}
}
class AccessNavigatorBuilder {
_navigate;
navigate(navigate) {
this._navigate = navigate;
return this;
}
build() {
if (!this._navigate) throw new Error("\u5BFC\u822A\u51FD\u6570\u662F\u5FC5\u987B\u8BBE\u7F6E\u7684\uFF0C\u8BF7\u68C0\u67E5\uFF01");
return new SimpleNavigator(this._navigate);
}
}
class AccessContextBuilder {
_recorder;
_voter;
_storer;
_matcher;
_navigator;
_hierarchy;
_validator;
_resources = [];
_navigate;
recorder(recorder) {
if ('function' == typeof recorder) this._recorder = recorder(new AccessRecorderBuilder());
else this._recorder = recorder;
return this;
}
voter(voter) {
if ('function' == typeof voter) this._voter = voter(new AccessVoterBuilder());
else this._voter = voter;
return this;
}
storer(storer) {
if ('function' == typeof storer) this._storer = storer(new AccessStorerBuilder());
else this._storer = storer;
return this;
}
matcher(matcher) {
if ('function' == typeof matcher) this._matcher = matcher(new AccessMatcherBuilder());
else this._matcher = matcher;
return this;
}
navigator(navigator) {
if ('function' == typeof navigator) this._navigator = navigator(new AccessNavigatorBuilder());
else this._navigator = navigator;
return this;
}
hierarchy(hierarchy) {
this._hierarchy = hierarchy;
return this;
}
validator(validator) {
this._validator = validator;
return this;
}
resource(builder) {
const resource = builder(new AccessResourceBuilder());
this._resources.push(resource);
return this;
}
navigate(navigate) {
this._navigate = navigate;
return this;
}
drs() {
this.resource((rb)=>rb.patterns('/login', '/logout', '/denied', '/signature').anonymous().build());
this.resource((rb)=>rb.patterns('/*').authenticated().build());
return this;
}
build() {
if (!this._recorder) this.recorder((builder)=>builder.build());
if (!this._voter) this.voter((builder)=>{
if (this._hierarchy) builder.hierarchy(this._hierarchy);
return builder.build();
});
if (!this._storer) this.storer((builder)=>{
if (this._validator) builder.authenticationValidator(this._validator);
return builder.build();
});
if (!this._matcher) {
if (0 === this._resources.length) this.drs();
this.matcher((builder)=>builder.resources(this._resources).build());
}
if (!this._navigator) this.navigator((builder)=>{
if (this._navigate) builder.navigate(this._navigate);
return builder.build();
});
return new SimpleContext(this._recorder, this._voter, this._storer, this._matcher, this._navigator);
}
}
class AccessHandlerBuilder {
_config;
config(config) {
this._config = config;
return this;
}
build() {
if (!this._config) throw new Error("\u884C\u4E3A\u914D\u7F6E\u662F\u5FC5\u987B\u8BBE\u7F6E\uFF0C\u8BF7\u68C0\u67E5\uFF01");
return new BehaveHandler(this._config);
}
}
class AccessBlockerBuilder {
_multi;
multi() {
this._multi = true;
return this;
}
single() {
this._multi = false;
return this;
}
build() {
if (this._multi) return new MultiBlocker();
return new SingleBlocker();
}
}
class AccessManagerBuilder {
_disabled = false;
_handler;
_blocker;
_behave;
disabled() {
this._disabled = true;
return this;
}
handler(handler) {
if ('function' == typeof handler) this._handler = handler(new AccessHandlerBuilder());
else this._handler = handler;
return this;
}
blocker(blocker) {
if ('function' == typeof blocker) this._blocker = blocker(new AccessBlockerBuilder());
else this._blocker = blocker;
return this;
}
behave(behave) {
this._behave = behave;
return this;
}
dbc() {
return this.behave({
notAuthenticationPath: '/login',
accessDeniedPath: '/denied',
notSignaturePath: '/signature'
});
}
build() {
if (!this._handler) this.handler((builder)=>{
if (!this._behave) this.dbc();
return builder.config(this._behave).build();
});
if (!this._blocker) this.blocker((builder)=>builder.single().build());
return new SimpleManager(this._disabled ?? false, this._handler, this._blocker);
}
}
class AccessGuarderBuilder {
_context;
_manager;
_addons = [];
_navigate;
context(context) {
if ('function' == typeof context) {
const builder = new AccessContextBuilder();
if (this._navigate) builder.navigate(this._navigate);
this._context = context(builder);
} else this._context = context;
return this;
}
manager(manager) {
if ('function' == typeof manager) this._manager = manager(new AccessManagerBuilder());
else this._manager = manager;
return this;
}
addons(...addons) {
for (const addon of addons)this._addons.push(addon);
return this;
}
navigate(navigate) {
this._navigate = navigate;
return this;
}
build() {
if (!this._context) this.context((builder)=>builder.build());
if (!this._manager) this.manager((builder)=>builder.build());
return {
context: this._context,
manager: this._manager,
guarder: new SimpleGuarder(this._context, this._manager, this._addons)
};
}
}
const SecurityContext = /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react__.createContext)(null);
const useSecurityContext = ()=>{
const sc = (0, __WEBPACK_EXTERNAL_MODULE_react__.useContext)(SecurityContext);
if (!sc) throw new Error("\u5B89\u5168\u4E0A\u4E0B\u6587\u4E3A\u7A7A\uFF0C\u5FC5\u987B\u4F7F\u7528\u5B89\u5168\u63D0\u4F9B\u8005\u5305\u88F9\u7EC4\u4EF6\u6765\u8BBE\u7F6E\u5B89\u5168\u4E0A\u4E0B\u6587");
return sc;
};
function SecurityProvider({ children, bundler }) {
const navigate = (0, __WEBPACK_EXTERNAL_MODULE_react_router_dom_5358f3fe__.useNavigate)();
const provide = (0, __WEBPACK_EXTERNAL_MODULE_react__.useMemo)(()=>bundler(new AccessGuarderBuilder().navigate(navigate)), [
bundler,
navigate
]);
return /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(SecurityContext.Provider, {
value: provide,
children: children
});
}
function SecurityBlocker({ children }) {
const { context, manager, guarder } = useSecurityContext();
if (manager.isDisabled()) return /*#__PURE__*/ (0, __WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.jsx)(__WEBPACK_EXTERNAL_MODULE_react_jsx_runtime_225474f2__.Fragment, {
children: children
});
const blocker = (0, __WEBPACK_EXTERNAL_MODULE_react_router_dom_5358f3fe__.useBlocker)(({ currentLocation, nextLocation })=>currentLocation.pathname !== nextLocation.pathname);
const [guarded, setGuarded] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(false);
const [nextPath, setNextPath] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)((0, __WEBPACK_EXTERNAL_MODULE_react_router_dom_5358f3fe__.useLocation)());
const [firstAccess, setFirstAccess] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(true);
const [firstHandle, setFirstHandle] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(true);
const [countSignature, setCountSignature] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(1);
const [handledDecision, setHandledDecision] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(false);
const [beforeDecision, setBeforeDecision] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(void 0);
const [currentDecision, setCurrentDecision] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(void 0);
const [securityBlock, setSecurityBlock] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(false);
const [executableBlocked, setExecutableBlocked] = (0, __WEBPACK_EXTERNAL_MODULE_react__.useState)(true);
(0, __WEBPACK_EXTERNAL_MODULE_react__.useEffect)(()=>{
if ('blocked' === blocker.state && executableBlocked) {
let isProceed;
const recorder = context.getRecorder();
const stayPath = recorder.getAllowPath();
const blockPath = blocker.location;
let guardBlocked = false;
if (securityBlock) guardBlocked = guarder.guardBlock(blockPath);
if (guardBlocked) {
setHandledDecision(false);
setCurrentDecision(void 0);
isProceed = false;
} else {
if (!beforeDecision) guarder.guardBefore(blockPath);
const blockedDecision = guarder.guardDecision(blockPath);
setHandledDecision(true);
setCurrentDecision(blockedDecision);
isProceed = blockedDecision === common_AccessDecision.allowAccess;
}
setNextPath(blockPath);
setExecutableBlocked(false);
if (isProceed) {
const isDiff = !!stayPath && stayPath.pathname !== blockPath.pathname;
if (isDiff) guarder.permitBefore(stayPath, blockPath);
blocker.proceed();
if (isDiff) guarder.permitAfter(stayPath, blockPath);
} else blocker.reset();
} else if ('unblocked' === blocker.state) {
if (handledDecision && currentDecision) {
let navNext;
const behave = guarder.guardHandle(currentDecision, beforeDecision);
switch(behave){
case common_AccessBehave.reDecision:
setBeforeDecision(currentDecision);
setSecurityBlock(false);
navNext = true;
break;
case common_AccessBehave.goNavigate:
setBeforeDecision(void 0);
navNext = false;
setSecurityBlock(false);
break;
case common_AccessBehave.doNothing:
default:
setBeforeDecision(void 0);
navNext = false;
setSecurityBlock(true);
break;
}
if (firstHandle && currentDecision === common_AccessDecision.notSignature && behave === common_AccessBehave.reDecision) if (countSignature >= 3) {
setFirstHandle(false);
setBeforeDecision(common_AccessDecision.notSignature);
setHandledDecision(true);
setCurrentDecision(common_AccessDecision.accessDenied);
} else {
const signDecision = guarder.guardDecision(nextPath);
setHandledDecision(true);
setBeforeDecision(void 0);
setCurrentDecision(signDecision);
setCountSignature(countSignature + 1);
}
else {
setFirstHandle(false);
setHandledDecision(false);
setCurrentDecision(void 0);
if (navNext) context.getNavigator().navigate(nextPath);
else {
guarder.guardAfter(nextPath, currentDecision);
setGuarded(true);
}
}
} else if (firstAccess) {
guarder.guardBefore(nextPath);
const firstDecision = guarder.guardDecision(nextPath);
setFirstAccess(false);
setHandledDecision(true);
setCurrentDecision(firstDecision);
}
if (!executableBlocked) setExecutableBlocked(true);
}
}, [
blocker,
context,
guarder,
nextPath,
firstAccess,
firstHandle,
countSignature,
handledDecision,
beforeDecision,
currentDecision,
securityBlock,
execu