@entur-partner/permission-client-node
Advanced tools
Comparing version 3.2.0 to 3.3.0
@@ -61,3 +61,3 @@ "use strict"; | ||
} | ||
catch (error) { | ||
catch { | ||
// ignore errors | ||
@@ -64,0 +64,0 @@ } |
@@ -27,3 +27,3 @@ "use strict"; | ||
this.cacheRefresh.refresh(); | ||
client.subscribe('/user/queue/application/' + applicationId, (message) => { | ||
client.subscribe('/user/queue/application/' + applicationId + '/instance/' + this.permissionRepository.getInstanceId(), (message) => { | ||
if (message.body === 'refresh-all') { | ||
@@ -30,0 +30,0 @@ this.cacheRefresh.refresh(); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.FetchHelper = void 0; | ||
const ValueObjects_1 = require("../ValueObjects"); | ||
class FetchHelper { | ||
@@ -36,3 +37,12 @@ constructor(tokenFactory) { | ||
if (!response.ok) { | ||
throw new Error(await response.text()); | ||
let error; | ||
try { | ||
const restException = JSON.parse(await response.text()); | ||
error = new ValueObjects_1.RestException(response.status, restException.title, restException.detail, restException.type, restException.instance); | ||
} | ||
catch { | ||
error = new ValueObjects_1.RestException(response.status, response.statusText, await response.text()); | ||
} | ||
console.log('**** throw ' + error); | ||
throw error; | ||
} | ||
@@ -39,0 +49,0 @@ const isJson = response.headers.get('content-type')?.includes('application/json'); |
@@ -12,4 +12,5 @@ "use strict"; | ||
this.APPLICATIONS_PERMISSIONS_PATH = 'applications/{0}/permissions'; | ||
this.APPLICATIONS_CHANGES_LATEST_PATH = 'applications/{0}/changes?resourceType=permission&scope=latest'; | ||
this.APPLICATIONS_CHANGES_SCOPE_PATH = 'applications/{0}/changes?resourceType=permission&scope={1}'; | ||
this.APPLICATIONS_INSTANCE_PERMISSIONS_PATH = 'applications/{0}/instances/{1}/permissions'; | ||
this.APPLICATIONS_CHANGES_LATEST_PATH = 'applications/{0}/instances/{1}/changes?resourceType=permission&scope=latest'; | ||
this.APPLICATIONS_CHANGES_SCOPE_PATH = 'applications/{0}/instances/{1}/changes?resourceType=permission&scope={2}'; | ||
this.AGREEMENTS_GET_PATH = 'agreements?operation={0}&access={1}&responsibilityType={2}&responsibilityKey={3}'; | ||
@@ -31,12 +32,12 @@ this.AGREEMENTS_POST_PATH = 'agreements'; | ||
} | ||
this.instanceId = BigInt(this.randomInt(Number.MAX_SAFE_INTEGER)); | ||
this.applicationPermission = []; | ||
} | ||
getInstanceId() { | ||
return this.instanceId; | ||
} | ||
async getApplicationId() { | ||
if (this.applicationId == null) { | ||
try { | ||
this.applicationId = await this.fetchHelper.post(this.url + this.APPLICATIONS_PATH, { | ||
name: this.application.name, | ||
refreshRate: this.application.refreshRate, | ||
permissionReleaseVersion: ValueObjects_1.PackageInfo.getVersion() + '-node', | ||
permissionReleaseCommit: null, | ||
}); | ||
this.applicationId = await this.registerApplicationInstance(); | ||
} | ||
@@ -61,6 +62,12 @@ catch (err) { | ||
try { | ||
await this.fetchHelper.post(this.url + this.APPLICATIONS_PERMISSIONS_PATH.replace('{0}', applicationId.toString()), applicationPermission); | ||
this.applicationPermission = await this.registerApplicationPermissions(applicationId, applicationPermission); | ||
} | ||
catch (err) { | ||
throw new Error(`Can not register permissions for application with ID ${applicationId}.`, { cause: err }); | ||
if (err instanceof ValueObjects_1.RestException && err.status == 404) { | ||
this.applicationId = await this.registerApplicationInstance(); | ||
this.applicationPermission = await this.registerApplicationPermissions(applicationId, applicationPermission); | ||
} | ||
else { | ||
throw err; | ||
} | ||
} | ||
@@ -72,4 +79,22 @@ } | ||
async getDeltaChanged() { | ||
const changes = await this.fetchHelper.get(this.url + | ||
this.APPLICATIONS_CHANGES_SCOPE_PATH.replace('{0}', (await this.getApplicationId()).toString()).replace('{1}', this.SCOPE_DELTA_START)); | ||
let changes; | ||
try { | ||
changes = await this.fetchHelper.get(this.url + | ||
this.APPLICATIONS_CHANGES_SCOPE_PATH.replace('{0}', (await this.getApplicationId()).toString()) | ||
.replace('{1}', this.instanceId.toString()) | ||
.replace('{2}', this.SCOPE_DELTA_START)); | ||
} | ||
catch (err) { | ||
if (err instanceof ValueObjects_1.RestException && err.status == 404) { | ||
this.applicationId = await this.registerApplicationInstance(); | ||
await this.registerApplicationPermissions(this.applicationId, this.applicationPermission); | ||
changes = await this.fetchHelper.get(this.url + | ||
this.APPLICATIONS_CHANGES_SCOPE_PATH.replace('{0}', (await this.getApplicationId()).toString()) | ||
.replace('{1}', this.instanceId.toString()) | ||
.replace('{2}', this.SCOPE_DELTA_START)); | ||
} | ||
else { | ||
throw err; | ||
} | ||
} | ||
changes[0].changedAt = new Date(changes[0].changedAt); // workarund since axios do not handle date well. | ||
@@ -89,3 +114,18 @@ // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
async getLastChanged() { | ||
const changes = await this.fetchHelper.get(this.url + this.APPLICATIONS_CHANGES_LATEST_PATH.replace('{0}', (await this.getApplicationId()).toString())); | ||
let changes; | ||
try { | ||
changes = await this.fetchHelper.get(this.url + | ||
this.APPLICATIONS_CHANGES_LATEST_PATH.replace('{0}', (await this.getApplicationId()).toString()).replace('{1}', this.instanceId.toString())); | ||
} | ||
catch (err) { | ||
if (err instanceof ValueObjects_1.RestException && err.status == 404) { | ||
this.applicationId = await this.registerApplicationInstance(); | ||
await this.registerApplicationPermissions(this.applicationId, this.applicationPermission); | ||
changes = await this.fetchHelper.get(this.url + | ||
this.APPLICATIONS_CHANGES_LATEST_PATH.replace('{0}', (await this.getApplicationId()).toString()).replace('{1}', this.instanceId.toString())); | ||
} | ||
else { | ||
throw err; | ||
} | ||
} | ||
return new Date(changes[0].changedAt); // workarund since axios do not handle date well. | ||
@@ -124,4 +164,20 @@ } | ||
} | ||
randomInt(max) { | ||
return Math.floor(Math.random() * max) + 1; | ||
} | ||
async registerApplicationInstance() { | ||
return await this.fetchHelper.post(this.url + this.APPLICATIONS_PATH, { | ||
name: this.application.name, | ||
instanceId: this.instanceId.toString(), | ||
refreshRate: this.application.refreshRate, | ||
permissionReleaseVersion: ValueObjects_1.PackageInfo.getVersion() + '-node', | ||
permissionReleaseCommit: null, | ||
}); | ||
} | ||
async registerApplicationPermissions(applicationId, applicationPermission) { | ||
await this.fetchHelper.post(this.url + this.APPLICATIONS_INSTANCE_PERMISSIONS_PATH.replace('{0}', applicationId.toString()).replace('{1}', this.instanceId.toString()), applicationPermission); | ||
return applicationPermission; | ||
} | ||
} | ||
exports.PermissionDeliverRepository = PermissionDeliverRepository; | ||
//# sourceMappingURL=PermissionDeliverRepository.js.map |
@@ -63,2 +63,10 @@ declare module '@entur-partner/permission-client-node/ValueObjects' { | ||
} | ||
export class RestException extends Error { | ||
readonly status: number; | ||
readonly title?: string | undefined; | ||
readonly detail?: string | undefined; | ||
readonly type?: string | undefined; | ||
readonly instance?: string | undefined; | ||
constructor(status: number, title?: string | undefined, detail?: string | undefined, type?: string | undefined, instance?: string | undefined); | ||
} | ||
@@ -211,2 +219,3 @@ } | ||
private readonly APPLICATIONS_PERMISSIONS_PATH; | ||
private readonly APPLICATIONS_INSTANCE_PERMISSIONS_PATH; | ||
private readonly APPLICATIONS_CHANGES_LATEST_PATH; | ||
@@ -223,3 +232,6 @@ private readonly APPLICATIONS_CHANGES_SCOPE_PATH; | ||
private applicationId; | ||
private instanceId; | ||
private applicationPermission; | ||
constructor(application: Application, tokenFactory: TokenFactory, permissionDeliverUrl: URL); | ||
getInstanceId(): bigint; | ||
getApplicationId(): Promise<bigint>; | ||
@@ -238,2 +250,5 @@ getRefreshRate(): number; | ||
deleteObject(objectKey: ObjectKey): Promise<void>; | ||
private randomInt; | ||
private registerApplicationInstance; | ||
private registerApplicationPermissions; | ||
} | ||
@@ -326,3 +341,3 @@ | ||
declare module '@entur-partner/permission-client-node/version' { | ||
const _default: "3.2.0"; | ||
const _default: "3.3.0"; | ||
export default _default; | ||
@@ -329,0 +344,0 @@ |
@@ -7,2 +7,3 @@ "use strict"; | ||
exports.AuthorizeCacheType = exports.ApplicationPermissionConverter = exports.ResponsibilitySetConverter = exports.JwtDecoder = exports.InMemoryCache = exports.PermissionDeliverRepository = exports.PermissionType = exports.CommunicationType = exports.RefreshType = exports.TokenFactory = void 0; | ||
exports.default = default_1; | ||
const InMemoryCache_1 = require("./cache/InMemoryCache"); | ||
@@ -38,3 +39,2 @@ var TokenFactory_1 = require("./jwt/TokenFactory"); | ||
} | ||
exports.default = default_1; | ||
//# sourceMappingURL=index.js.map |
@@ -6,3 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.CommunicationType = exports.RefreshType = exports.PackageInfo = exports.PermissionType = void 0; | ||
exports.RestException = exports.CommunicationType = exports.RefreshType = exports.PackageInfo = exports.PermissionType = void 0; | ||
const version_1 = __importDefault(require("./version")); | ||
@@ -30,2 +30,13 @@ var PermissionType; | ||
})(CommunicationType || (exports.CommunicationType = CommunicationType = {})); | ||
class RestException extends Error { | ||
constructor(status, title, detail, type, instance) { | ||
super(detail ?? title); | ||
this.status = status; | ||
this.title = title; | ||
this.detail = detail; | ||
this.type = type; | ||
this.instance = instance; | ||
} | ||
} | ||
exports.RestException = RestException; | ||
//# sourceMappingURL=ValueObjects.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
// This file is automatically generated by utils/UpdateVersionFile.cjs | ||
exports.default = '3.2.0'; | ||
exports.default = '3.3.0'; | ||
//# sourceMappingURL=version.js.map |
@@ -35,3 +35,3 @@ import { CommunicationType, RefreshType } from '../ValueObjects.js'; | ||
} | ||
catch (error) { | ||
catch { | ||
// ignore errors | ||
@@ -38,0 +38,0 @@ } |
@@ -24,3 +24,3 @@ import { w3cwebsocket } from 'websocket'; | ||
this.cacheRefresh.refresh(); | ||
client.subscribe('/user/queue/application/' + applicationId, (message) => { | ||
client.subscribe('/user/queue/application/' + applicationId + '/instance/' + this.permissionRepository.getInstanceId(), (message) => { | ||
if (message.body === 'refresh-all') { | ||
@@ -27,0 +27,0 @@ this.cacheRefresh.refresh(); |
@@ -0,1 +1,2 @@ | ||
import { RestException } from '../ValueObjects.js'; | ||
export class FetchHelper { | ||
@@ -33,3 +34,12 @@ constructor(tokenFactory) { | ||
if (!response.ok) { | ||
throw new Error(await response.text()); | ||
let error; | ||
try { | ||
const restException = JSON.parse(await response.text()); | ||
error = new RestException(response.status, restException.title, restException.detail, restException.type, restException.instance); | ||
} | ||
catch { | ||
error = new RestException(response.status, response.statusText, await response.text()); | ||
} | ||
console.log('**** throw ' + error); | ||
throw error; | ||
} | ||
@@ -36,0 +46,0 @@ const isJson = response.headers.get('content-type')?.includes('application/json'); |
@@ -1,2 +0,2 @@ | ||
import { PackageInfo, } from '../ValueObjects.js'; | ||
import { PackageInfo, RestException, } from '../ValueObjects.js'; | ||
import { FetchHelper } from './FetchHelper.js'; | ||
@@ -9,4 +9,5 @@ export class PermissionDeliverRepository { | ||
this.APPLICATIONS_PERMISSIONS_PATH = 'applications/{0}/permissions'; | ||
this.APPLICATIONS_CHANGES_LATEST_PATH = 'applications/{0}/changes?resourceType=permission&scope=latest'; | ||
this.APPLICATIONS_CHANGES_SCOPE_PATH = 'applications/{0}/changes?resourceType=permission&scope={1}'; | ||
this.APPLICATIONS_INSTANCE_PERMISSIONS_PATH = 'applications/{0}/instances/{1}/permissions'; | ||
this.APPLICATIONS_CHANGES_LATEST_PATH = 'applications/{0}/instances/{1}/changes?resourceType=permission&scope=latest'; | ||
this.APPLICATIONS_CHANGES_SCOPE_PATH = 'applications/{0}/instances/{1}/changes?resourceType=permission&scope={2}'; | ||
this.AGREEMENTS_GET_PATH = 'agreements?operation={0}&access={1}&responsibilityType={2}&responsibilityKey={3}'; | ||
@@ -28,12 +29,12 @@ this.AGREEMENTS_POST_PATH = 'agreements'; | ||
} | ||
this.instanceId = BigInt(this.randomInt(Number.MAX_SAFE_INTEGER)); | ||
this.applicationPermission = []; | ||
} | ||
getInstanceId() { | ||
return this.instanceId; | ||
} | ||
async getApplicationId() { | ||
if (this.applicationId == null) { | ||
try { | ||
this.applicationId = await this.fetchHelper.post(this.url + this.APPLICATIONS_PATH, { | ||
name: this.application.name, | ||
refreshRate: this.application.refreshRate, | ||
permissionReleaseVersion: PackageInfo.getVersion() + '-node', | ||
permissionReleaseCommit: null, | ||
}); | ||
this.applicationId = await this.registerApplicationInstance(); | ||
} | ||
@@ -58,6 +59,12 @@ catch (err) { | ||
try { | ||
await this.fetchHelper.post(this.url + this.APPLICATIONS_PERMISSIONS_PATH.replace('{0}', applicationId.toString()), applicationPermission); | ||
this.applicationPermission = await this.registerApplicationPermissions(applicationId, applicationPermission); | ||
} | ||
catch (err) { | ||
throw new Error(`Can not register permissions for application with ID ${applicationId}.`, { cause: err }); | ||
if (err instanceof RestException && err.status == 404) { | ||
this.applicationId = await this.registerApplicationInstance(); | ||
this.applicationPermission = await this.registerApplicationPermissions(applicationId, applicationPermission); | ||
} | ||
else { | ||
throw err; | ||
} | ||
} | ||
@@ -69,4 +76,22 @@ } | ||
async getDeltaChanged() { | ||
const changes = await this.fetchHelper.get(this.url + | ||
this.APPLICATIONS_CHANGES_SCOPE_PATH.replace('{0}', (await this.getApplicationId()).toString()).replace('{1}', this.SCOPE_DELTA_START)); | ||
let changes; | ||
try { | ||
changes = await this.fetchHelper.get(this.url + | ||
this.APPLICATIONS_CHANGES_SCOPE_PATH.replace('{0}', (await this.getApplicationId()).toString()) | ||
.replace('{1}', this.instanceId.toString()) | ||
.replace('{2}', this.SCOPE_DELTA_START)); | ||
} | ||
catch (err) { | ||
if (err instanceof RestException && err.status == 404) { | ||
this.applicationId = await this.registerApplicationInstance(); | ||
await this.registerApplicationPermissions(this.applicationId, this.applicationPermission); | ||
changes = await this.fetchHelper.get(this.url + | ||
this.APPLICATIONS_CHANGES_SCOPE_PATH.replace('{0}', (await this.getApplicationId()).toString()) | ||
.replace('{1}', this.instanceId.toString()) | ||
.replace('{2}', this.SCOPE_DELTA_START)); | ||
} | ||
else { | ||
throw err; | ||
} | ||
} | ||
changes[0].changedAt = new Date(changes[0].changedAt); // workarund since axios do not handle date well. | ||
@@ -86,3 +111,18 @@ // eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
async getLastChanged() { | ||
const changes = await this.fetchHelper.get(this.url + this.APPLICATIONS_CHANGES_LATEST_PATH.replace('{0}', (await this.getApplicationId()).toString())); | ||
let changes; | ||
try { | ||
changes = await this.fetchHelper.get(this.url + | ||
this.APPLICATIONS_CHANGES_LATEST_PATH.replace('{0}', (await this.getApplicationId()).toString()).replace('{1}', this.instanceId.toString())); | ||
} | ||
catch (err) { | ||
if (err instanceof RestException && err.status == 404) { | ||
this.applicationId = await this.registerApplicationInstance(); | ||
await this.registerApplicationPermissions(this.applicationId, this.applicationPermission); | ||
changes = await this.fetchHelper.get(this.url + | ||
this.APPLICATIONS_CHANGES_LATEST_PATH.replace('{0}', (await this.getApplicationId()).toString()).replace('{1}', this.instanceId.toString())); | ||
} | ||
else { | ||
throw err; | ||
} | ||
} | ||
return new Date(changes[0].changedAt); // workarund since axios do not handle date well. | ||
@@ -121,3 +161,19 @@ } | ||
} | ||
randomInt(max) { | ||
return Math.floor(Math.random() * max) + 1; | ||
} | ||
async registerApplicationInstance() { | ||
return await this.fetchHelper.post(this.url + this.APPLICATIONS_PATH, { | ||
name: this.application.name, | ||
instanceId: this.instanceId.toString(), | ||
refreshRate: this.application.refreshRate, | ||
permissionReleaseVersion: PackageInfo.getVersion() + '-node', | ||
permissionReleaseCommit: null, | ||
}); | ||
} | ||
async registerApplicationPermissions(applicationId, applicationPermission) { | ||
await this.fetchHelper.post(this.url + this.APPLICATIONS_INSTANCE_PERMISSIONS_PATH.replace('{0}', applicationId.toString()).replace('{1}', this.instanceId.toString()), applicationPermission); | ||
return applicationPermission; | ||
} | ||
} | ||
//# sourceMappingURL=PermissionDeliverRepository.js.map |
@@ -22,2 +22,12 @@ import version from './version.js'; | ||
})(CommunicationType || (CommunicationType = {})); | ||
export class RestException extends Error { | ||
constructor(status, title, detail, type, instance) { | ||
super(detail ?? title); | ||
this.status = status; | ||
this.title = title; | ||
this.detail = detail; | ||
this.type = type; | ||
this.instance = instance; | ||
} | ||
} | ||
//# sourceMappingURL=ValueObjects.js.map |
// This file is automatically generated by utils/UpdateVersionFile.cjs | ||
export default '3.2.0'; | ||
export default '3.3.0'; | ||
//# sourceMappingURL=version.js.map |
{ | ||
"name": "@entur-partner/permission-client-node", | ||
"version": "3.2.0", | ||
"version": "3.3.0", | ||
"author": "Entur AS", | ||
@@ -23,3 +23,3 @@ "contributors": [ | ||
"format": "prettier --write \"src/**/*.ts\" ", | ||
"lint": "eslint -c .eslintrc.cjs --ext .ts src/", | ||
"lint": "eslint -c eslint.config.mjs src/", | ||
"test": "jest --config jestconfig.json --testResultsProcessor=./node_modules/jest-sonar-reporter/index.js --collectCoverage=true --coverageDirectory=reports/jest/coverage/ --coverageReporters=lcov", | ||
@@ -46,18 +46,21 @@ "prepare": "npm run build", | ||
"devDependencies": { | ||
"@eslint/js": "^9.9.0", | ||
"@types/jest": "^29.5.12", | ||
"@types/websocket": "^1.0.9", | ||
"@typescript-eslint/eslint-plugin": "^7.0.1", | ||
"@typescript-eslint/parser": "^7.0.1", | ||
"audit-ci": "^6.6.1", | ||
"@typescript-eslint/eslint-plugin": "^8.1.0", | ||
"@typescript-eslint/parser": "^8.1.0", | ||
"audit-ci": "^7.1.0", | ||
"echo-cli": "^2.0.0", | ||
"eslint": "^8.56.0", | ||
"eslint": "^9.9.0", | ||
"eslint-config-prettier": "^9.0.0", | ||
"globals": "^15.9.0", | ||
"jest": "^29.7.0", | ||
"jest-sonar-reporter": "^2.0.0", | ||
"npm-dts": "^1.3.12", | ||
"prettier": "^3.2.5", | ||
"ts-jest": "^29.1.2", | ||
"npm-dts": "^1.3.13", | ||
"prettier": "^3.3.3", | ||
"ts-jest": "^29.2.4", | ||
"ts-node-dev": "^2.0.0", | ||
"tsc-alias": "1.8.8", | ||
"typescript": "^5.3.3" | ||
"tsc-alias": "^1.8.10", | ||
"typescript": "^5.5.4", | ||
"typescript-eslint": "^8.1.0" | ||
}, | ||
@@ -75,4 +78,4 @@ "files": [ | ||
"@stomp/stompjs": "^7.0.0", | ||
"websocket": "^1.0.34" | ||
"websocket": "^1.0.35" | ||
} | ||
} |
@@ -212,2 +212,9 @@ # Permission Client for Node | ||
## Miscellaneous | ||
### Use Permission Store without downtime | ||
Starting from version 3.0.0 of Permission Client, each instance of your running service will receive a unique instance ID. | ||
This ID is used to track the permissions required by your service, | ||
allowing Permission Store to calculate the total permission requirements for your application. | ||
When introducing new permissions, it's sometimes necessary to add them to application.yaml before using them in your code. | ||
This ensures that role management can be performed before the corresponding restrictions are enforced during code execution. | ||
@@ -214,0 +221,0 @@ ### Get source |
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
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
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
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
174519
2022
248
19