@fonoster/authz 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +32 -0
- package/dist/client/AuthzClient.d.ts +40 -0
- package/dist/client/AuthzClient.js +152 -0
- package/dist/client/AuthzServiceClient.d.ts +19 -0
- package/dist/client/AuthzServiceClient.js +2 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.js +36 -0
- package/dist/createCheckMethodAuthorized.d.ts +12 -0
- package/dist/createCheckMethodAuthorized.js +72 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +37 -0
- package/dist/server/AuthzServer.d.ts +6 -0
- package/dist/server/AuthzServer.js +168 -0
- package/dist/server/DummyAuthzHandler.d.ts +8 -0
- package/dist/server/DummyAuthzHandler.js +41 -0
- package/dist/server/defaultServerConfig.d.ts +3 -0
- package/dist/server/defaultServerConfig.js +8 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +35 -0
- package/dist/server/server.d.ts +1 -0
- package/dist/server/server.js +26 -0
- package/dist/serviceDefinition.d.ts +2 -0
- package/dist/serviceDefinition.js +29 -0
- package/dist/types.d.ts +23 -0
- package/dist/types.js +2 -0
- package/package.json +44 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 Fonoster Inc
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
authz
|
|
2
|
+
=================
|
|
3
|
+
|
|
4
|
+
[](https://fonoster.com)
|
|
5
|
+
[](https://npmjs.org/package/@fonoster/authz)
|
|
6
|
+
[](https://npmjs.org/package/@fonoster/authz)
|
|
7
|
+
[](https://github.com/fonoster/fonoster/blob/main/package.json)
|
|
8
|
+
|
|
9
|
+
Authz is a simple and extensible authorization module for Fonoster. It provides a way to authorize incoming phone and API calls.
|
|
10
|
+
|
|
11
|
+
The module has a simple interface that allows you to create authorization strategies. That includes verifying if a session is authorized, if a GRPC method is authorized, charging an account, and getting the account balance.
|
|
12
|
+
|
|
13
|
+
The interface is defined as follows:
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
type AuthzHandler = {
|
|
17
|
+
checkSessionAuthorized(request: VoiceRequest): Promise<boolean>;
|
|
18
|
+
checkMethodAuthorized(
|
|
19
|
+
request: CheckMethodAuthorizedRequest
|
|
20
|
+
): Promise<boolean>;
|
|
21
|
+
chargeAccount(request: ChargeAccountRequest): Promise<void>;
|
|
22
|
+
getAccountBalance(request: GetAccountBalanceRequest): Promise<number>;
|
|
23
|
+
};
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Please look at the [DummyAuthzHandler](./src/server/DummyAuthzHandler.ts) for an example of implementing your authorization strategy.
|
|
27
|
+
|
|
28
|
+
## Enabling the Authz module
|
|
29
|
+
|
|
30
|
+
To enable the Authz module you need to set the `AUTHZ_SERVICE_ENABLED` environment variable to `true`. Also, you need the `AUTHZ_SERVICE_HOST` (required), `AUTHZ_SERVICE_PORT` (defaults), and `AUTHZ_SERVICE_METHODS` (default is `/fonoster.calls.v1beta2.Calls/CreateCall`) environment variables.
|
|
31
|
+
|
|
32
|
+
Imagine you want to authorize the creation of new Workspaces. You can add the `/fonoster.workspaces.v1beta2.Workspaces/CreateWorkspace` method to the `AUTHZ_SERVICE_METHODS` environment variable and implement the `checkMethodAuthorized` method in your AuthzHandler.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { CheckMethodAuthorizedRequest, ChargeAccountRequest, GetAccountBalanceRequest, VoiceRequest } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* AuthzClient class to interact with the AuthzServer via gRPC.
|
|
4
|
+
*/
|
|
5
|
+
export declare class AuthzClient {
|
|
6
|
+
private readonly client;
|
|
7
|
+
/**
|
|
8
|
+
* Initializes the AuthzClient with the given configuration.
|
|
9
|
+
* @param address The address of the AuthzServer (e.g., "localhost:50051").
|
|
10
|
+
*/
|
|
11
|
+
constructor(address: string);
|
|
12
|
+
/**
|
|
13
|
+
* Checks if the session is authorized.
|
|
14
|
+
* @param request VoiceRequest containing session details.
|
|
15
|
+
* @returns Promise resolving to a boolean indicating authorization.
|
|
16
|
+
*/
|
|
17
|
+
checkSessionAuthorized(request: VoiceRequest): Promise<boolean>;
|
|
18
|
+
/**
|
|
19
|
+
* Checks if a specific method is authorized.
|
|
20
|
+
* @param request CheckMethodAuthorizedRequest containing accessKeyId and method.
|
|
21
|
+
* @returns Promise resolving to a boolean indicating authorization.
|
|
22
|
+
*/
|
|
23
|
+
checkMethodAuthorized(request: CheckMethodAuthorizedRequest): Promise<boolean>;
|
|
24
|
+
/**
|
|
25
|
+
* Charges an account by a specified amount.
|
|
26
|
+
* @param request ChargeAccountRequest containing accessKeyId and amount.
|
|
27
|
+
* @returns Promise resolving when the charge is successful.
|
|
28
|
+
*/
|
|
29
|
+
chargeAccount(request: ChargeAccountRequest): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* Retrieves the account balance.
|
|
32
|
+
* @param request GetAccountBalanceRequest containing accessKeyId.
|
|
33
|
+
* @returns Promise resolving to the account balance.
|
|
34
|
+
*/
|
|
35
|
+
getAccountBalance(request: GetAccountBalanceRequest): Promise<number>;
|
|
36
|
+
/**
|
|
37
|
+
* Closes the gRPC client connection.
|
|
38
|
+
*/
|
|
39
|
+
close(): void;
|
|
40
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.AuthzClient = void 0;
|
|
37
|
+
/*
|
|
38
|
+
* Copyright (C) 2024 by Fonoster Inc (https://fonoster.com)
|
|
39
|
+
* http://github.com/fonoster/fonoster
|
|
40
|
+
*
|
|
41
|
+
* This file is part of Fonoster
|
|
42
|
+
*
|
|
43
|
+
* Licensed under the MIT License (the "License");
|
|
44
|
+
* you may not use this file except in compliance with
|
|
45
|
+
* the License. You may obtain a copy of the License at
|
|
46
|
+
*
|
|
47
|
+
* https://opensource.org/licenses/MIT
|
|
48
|
+
*
|
|
49
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
50
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
51
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
52
|
+
* See the License for the specific language governing permissions and
|
|
53
|
+
* limitations under the License.
|
|
54
|
+
*/
|
|
55
|
+
const grpc = __importStar(require("@grpc/grpc-js"));
|
|
56
|
+
const serviceDefinition_1 = require("../serviceDefinition");
|
|
57
|
+
/**
|
|
58
|
+
* AuthzClient class to interact with the AuthzServer via gRPC.
|
|
59
|
+
*/
|
|
60
|
+
class AuthzClient {
|
|
61
|
+
/**
|
|
62
|
+
* Initializes the AuthzClient with the given configuration.
|
|
63
|
+
* @param address The address of the AuthzServer (e.g., "localhost:50051").
|
|
64
|
+
*/
|
|
65
|
+
constructor(address) {
|
|
66
|
+
this.client = new (grpc.makeGenericClientConstructor(serviceDefinition_1.serviceDefinition, "AuthzService", {}))(address, grpc.credentials.createInsecure());
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Checks if the session is authorized.
|
|
70
|
+
* @param request VoiceRequest containing session details.
|
|
71
|
+
* @returns Promise resolving to a boolean indicating authorization.
|
|
72
|
+
*/
|
|
73
|
+
async checkSessionAuthorized(request) {
|
|
74
|
+
return new Promise((resolve, reject) => {
|
|
75
|
+
this.client.checkSessionAuthorized(request, (error, response) => {
|
|
76
|
+
if (error) {
|
|
77
|
+
reject(new Error(`checkSessionAuthorized failed: ${error.message || error}`));
|
|
78
|
+
}
|
|
79
|
+
else if (response && typeof response.authorized === "boolean") {
|
|
80
|
+
resolve(response.authorized);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
reject(new Error(`checkSessionAuthorized failed: Invalid response format.`));
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Checks if a specific method is authorized.
|
|
90
|
+
* @param request CheckMethodAuthorizedRequest containing accessKeyId and method.
|
|
91
|
+
* @returns Promise resolving to a boolean indicating authorization.
|
|
92
|
+
*/
|
|
93
|
+
async checkMethodAuthorized(request) {
|
|
94
|
+
return new Promise((resolve, reject) => {
|
|
95
|
+
this.client.checkMethodAuthorized(request, (error, response) => {
|
|
96
|
+
if (error) {
|
|
97
|
+
reject(new Error(`checkMethodAuthorized failed: ${error.message || error}`));
|
|
98
|
+
}
|
|
99
|
+
else if (response && typeof response.authorized === "boolean") {
|
|
100
|
+
resolve(response.authorized);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
reject(new Error(`checkMethodAuthorized failed: Invalid response format.`));
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Charges an account by a specified amount.
|
|
110
|
+
* @param request ChargeAccountRequest containing accessKeyId and amount.
|
|
111
|
+
* @returns Promise resolving when the charge is successful.
|
|
112
|
+
*/
|
|
113
|
+
async chargeAccount(request) {
|
|
114
|
+
return new Promise((resolve, reject) => {
|
|
115
|
+
this.client.chargeAccount(request, (error, _response) => {
|
|
116
|
+
if (error) {
|
|
117
|
+
reject(new Error(`chargeAccount failed: ${error.message || error}`));
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
resolve();
|
|
121
|
+
}
|
|
122
|
+
});
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Retrieves the account balance.
|
|
127
|
+
* @param request GetAccountBalanceRequest containing accessKeyId.
|
|
128
|
+
* @returns Promise resolving to the account balance.
|
|
129
|
+
*/
|
|
130
|
+
async getAccountBalance(request) {
|
|
131
|
+
return new Promise((resolve, reject) => {
|
|
132
|
+
this.client.getAccountBalance(request, (error, response) => {
|
|
133
|
+
if (error) {
|
|
134
|
+
reject(new Error(`getAccountBalance failed: ${error.message || error}`));
|
|
135
|
+
}
|
|
136
|
+
else if (response && typeof response.balance === "number") {
|
|
137
|
+
resolve(response.balance);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
reject(new Error(`getAccountBalance failed: Invalid response format.`));
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Closes the gRPC client connection.
|
|
147
|
+
*/
|
|
148
|
+
close() {
|
|
149
|
+
this.client.close();
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
exports.AuthzClient = AuthzClient;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as grpc from "@grpc/grpc-js";
|
|
2
|
+
import { CheckMethodAuthorizedRequest, ChargeAccountRequest, GetAccountBalanceRequest, VoiceRequest } from "../types";
|
|
3
|
+
/**
|
|
4
|
+
* Interface representing the AuthzService client methods.
|
|
5
|
+
* This should match the service definition used by the server.
|
|
6
|
+
*/
|
|
7
|
+
interface AuthzServiceClient extends grpc.Client {
|
|
8
|
+
checkSessionAuthorized(request: VoiceRequest, callback: grpc.requestCallback<{
|
|
9
|
+
authorized: boolean;
|
|
10
|
+
}>): void;
|
|
11
|
+
checkMethodAuthorized(request: CheckMethodAuthorizedRequest, callback: grpc.requestCallback<{
|
|
12
|
+
authorized: boolean;
|
|
13
|
+
}>): void;
|
|
14
|
+
chargeAccount(request: ChargeAccountRequest, callback: grpc.requestCallback<{}>): void;
|
|
15
|
+
getAccountBalance(request: GetAccountBalanceRequest, callback: grpc.requestCallback<{
|
|
16
|
+
balance: number;
|
|
17
|
+
}>): void;
|
|
18
|
+
}
|
|
19
|
+
export { AuthzServiceClient };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
/*
|
|
18
|
+
* Copyright (C) 2024 by Fonoster Inc (https://fonoster.com)
|
|
19
|
+
* http://github.com/fonoster/fonoster
|
|
20
|
+
*
|
|
21
|
+
* This file is part of Fonoster
|
|
22
|
+
*
|
|
23
|
+
* Licensed under the MIT License (the "License");
|
|
24
|
+
* you may not use this file except in compliance with
|
|
25
|
+
* the License. You may obtain a copy of the License at
|
|
26
|
+
*
|
|
27
|
+
* https://opensource.org/licenses/MIT
|
|
28
|
+
*
|
|
29
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
30
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
31
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
32
|
+
* See the License for the specific language governing permissions and
|
|
33
|
+
* limitations under the License.
|
|
34
|
+
*/
|
|
35
|
+
__exportStar(require("./AuthzClient"), exports);
|
|
36
|
+
__exportStar(require("./AuthzServiceClient"), exports);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ServerInterceptingCall } from "@grpc/grpc-js";
|
|
2
|
+
/**
|
|
3
|
+
* This function is a gRPC interceptor that checks if the request a method is authorized
|
|
4
|
+
* to be called by the user.
|
|
5
|
+
*
|
|
6
|
+
* @param {string} authzServer - The public key to validate the token
|
|
7
|
+
* @return {Function} - The gRPC interceptor
|
|
8
|
+
*/
|
|
9
|
+
declare function createCheckMethodAuthorized(authzServer: string, methods: string[]): (methodDefinition: {
|
|
10
|
+
path: string;
|
|
11
|
+
}, call: ServerInterceptingCall) => ServerInterceptingCall;
|
|
12
|
+
export { createCheckMethodAuthorized };
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createCheckMethodAuthorized = createCheckMethodAuthorized;
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (C) 2024 by Fonoster Inc (https://fonoster.com)
|
|
6
|
+
* http://github.com/fonoster/fonoster
|
|
7
|
+
*
|
|
8
|
+
* This file is part of Fonoster
|
|
9
|
+
*
|
|
10
|
+
* Licensed under the MIT License (the "License");
|
|
11
|
+
* you may not use this file except in compliance with
|
|
12
|
+
* the License. You may obtain a copy of the License at
|
|
13
|
+
*
|
|
14
|
+
* https://opensource.org/licenses/MIT
|
|
15
|
+
*
|
|
16
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
18
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
19
|
+
* See the License for the specific language governing permissions and
|
|
20
|
+
* limitations under the License.
|
|
21
|
+
*/
|
|
22
|
+
const logger_1 = require("@fonoster/logger");
|
|
23
|
+
const grpc_js_1 = require("@grpc/grpc-js");
|
|
24
|
+
const AuthzClient_1 = require("./client/AuthzClient");
|
|
25
|
+
const identity_1 = require("@fonoster/identity");
|
|
26
|
+
const logger = (0, logger_1.getLogger)({ service: "authz", filePath: __filename });
|
|
27
|
+
/**
|
|
28
|
+
* This function is a gRPC interceptor that checks if the request a method is authorized
|
|
29
|
+
* to be called by the user.
|
|
30
|
+
*
|
|
31
|
+
* @param {string} authzServer - The public key to validate the token
|
|
32
|
+
* @return {Function} - The gRPC interceptor
|
|
33
|
+
*/
|
|
34
|
+
function createCheckMethodAuthorized(authzServer, methods) {
|
|
35
|
+
logger.verbose("creating check method authorized interceptor", {
|
|
36
|
+
authzServer,
|
|
37
|
+
methods
|
|
38
|
+
});
|
|
39
|
+
const authz = new AuthzClient_1.AuthzClient(authzServer);
|
|
40
|
+
/**
|
|
41
|
+
* Inner function that will be called by the gRPC server.
|
|
42
|
+
*
|
|
43
|
+
* @param {object} methodDefinition - The method definition
|
|
44
|
+
* @param {string} methodDefinition.path - The path of the gRPC method
|
|
45
|
+
* @param {ServerInterceptingCall} call - The call object
|
|
46
|
+
* @return {ServerInterceptingCall} - The modified call object
|
|
47
|
+
*/
|
|
48
|
+
return (methodDefinition, call) => {
|
|
49
|
+
const { path: method } = methodDefinition;
|
|
50
|
+
if (!methods.includes(method)) {
|
|
51
|
+
// Ignore the check if the method is not in the list
|
|
52
|
+
logger.silly("method is not in the list", { method });
|
|
53
|
+
return call;
|
|
54
|
+
}
|
|
55
|
+
logger.silly("checking if method is authorized", { method });
|
|
56
|
+
const accessKeyId = (0, identity_1.getAccessKeyIdFromCall)(call);
|
|
57
|
+
authz
|
|
58
|
+
.checkMethodAuthorized({
|
|
59
|
+
accessKeyId,
|
|
60
|
+
method
|
|
61
|
+
})
|
|
62
|
+
.then(() => {
|
|
63
|
+
call.sendMessage({ authorized: true }, () => {
|
|
64
|
+
logger.silly("method is authorized", { method });
|
|
65
|
+
});
|
|
66
|
+
}).catch((error) => {
|
|
67
|
+
logger.error("error checking if method is authorized", { method, error });
|
|
68
|
+
call.sendStatus({ code: grpc_js_1.status.PERMISSION_DENIED, details: `Method ${method} is not authorized for accessKeyId ${accessKeyId}` });
|
|
69
|
+
});
|
|
70
|
+
return call;
|
|
71
|
+
};
|
|
72
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
/*
|
|
18
|
+
* Copyright (C) 2024 by Fonoster Inc (https://fonoster.com)
|
|
19
|
+
* http://github.com/fonoster/fonoster
|
|
20
|
+
*
|
|
21
|
+
* This file is part of Fonoster
|
|
22
|
+
*
|
|
23
|
+
* Licensed under the MIT License (the "License");
|
|
24
|
+
* you may not use this file except in compliance with
|
|
25
|
+
* the License. You may obtain a copy of the License at
|
|
26
|
+
*
|
|
27
|
+
* https://opensource.org/licenses/MIT
|
|
28
|
+
*
|
|
29
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
30
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
31
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
32
|
+
* See the License for the specific language governing permissions and
|
|
33
|
+
* limitations under the License.
|
|
34
|
+
*/
|
|
35
|
+
__exportStar(require("./server"), exports);
|
|
36
|
+
__exportStar(require("./client"), exports);
|
|
37
|
+
__exportStar(require("./createCheckMethodAuthorized"), exports);
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
/*
|
|
40
|
+
* Copyright (C) 2024 by Fonoster Inc (https://fonoster.com)
|
|
41
|
+
* http://github.com/fonoster/fonoster
|
|
42
|
+
*
|
|
43
|
+
* This file is part of Fonoster
|
|
44
|
+
*
|
|
45
|
+
* Licensed under the MIT License (the "License");
|
|
46
|
+
* you may not use this file except in compliance with
|
|
47
|
+
* the License. You may obtain a copy of the License at
|
|
48
|
+
*
|
|
49
|
+
* https://opensource.org/licenses/MIT
|
|
50
|
+
*
|
|
51
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
52
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
53
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
54
|
+
* See the License for the specific language governing permissions and
|
|
55
|
+
* limitations under the License.
|
|
56
|
+
*/
|
|
57
|
+
const common_1 = require("@fonoster/common");
|
|
58
|
+
const logger_1 = require("@fonoster/logger");
|
|
59
|
+
const grpc = __importStar(require("@grpc/grpc-js"));
|
|
60
|
+
const deepmerge_1 = __importDefault(require("deepmerge"));
|
|
61
|
+
const grpc_health_check_1 = require("grpc-health-check");
|
|
62
|
+
const defaultServerConfig_1 = require("./defaultServerConfig");
|
|
63
|
+
const serviceDefinition_1 = require("../serviceDefinition");
|
|
64
|
+
const logger = (0, logger_1.getLogger)({ service: "authz", filePath: __filename });
|
|
65
|
+
class AuthzServer {
|
|
66
|
+
constructor(config = defaultServerConfig_1.defaultServerConfig) {
|
|
67
|
+
this.config = (0, deepmerge_1.default)(defaultServerConfig_1.defaultServerConfig, config);
|
|
68
|
+
}
|
|
69
|
+
async listen(handler) {
|
|
70
|
+
try {
|
|
71
|
+
const healthImpl = new grpc_health_check_1.HealthImplementation(common_1.statusMap);
|
|
72
|
+
const credentials = await (0, common_1.getServerCredentials)({});
|
|
73
|
+
const server = new grpc.Server();
|
|
74
|
+
server.addService(serviceDefinition_1.serviceDefinition, {
|
|
75
|
+
checkSessionAuthorized: async (call, callback) => {
|
|
76
|
+
logger.verbose("checkSessionAuthorized called");
|
|
77
|
+
logger.verbose(JSON.stringify(call.request));
|
|
78
|
+
try {
|
|
79
|
+
const isAuthorized = await handler.checkSessionAuthorized(call.request);
|
|
80
|
+
if (isAuthorized) {
|
|
81
|
+
callback(null, { authorized: true });
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
callback({
|
|
85
|
+
code: grpc.status.PERMISSION_DENIED,
|
|
86
|
+
message: "Session is not authorized."
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
logger.error("Error in checkSessionAuthorized:", error);
|
|
92
|
+
callback({
|
|
93
|
+
code: grpc.status.INTERNAL,
|
|
94
|
+
message: "Internal server error."
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
checkMethodAuthorized: async (call, callback) => {
|
|
99
|
+
logger.verbose("checkMethodAuthorized called");
|
|
100
|
+
logger.verbose(JSON.stringify(call.request));
|
|
101
|
+
try {
|
|
102
|
+
const isAuthorized = await handler.checkMethodAuthorized(call.request);
|
|
103
|
+
if (isAuthorized) {
|
|
104
|
+
callback(null, { authorized: true });
|
|
105
|
+
}
|
|
106
|
+
else {
|
|
107
|
+
callback({
|
|
108
|
+
code: grpc.status.PERMISSION_DENIED,
|
|
109
|
+
message: "Method is not authorized."
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
catch (error) {
|
|
114
|
+
logger.error("Error in checkMethodAuthorized:", error);
|
|
115
|
+
callback({
|
|
116
|
+
code: grpc.status.INTERNAL,
|
|
117
|
+
message: "Internal server error."
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
},
|
|
121
|
+
chargeAccount: async (call, callback) => {
|
|
122
|
+
logger.verbose("chargeAccount called");
|
|
123
|
+
logger.verbose(JSON.stringify(call.request));
|
|
124
|
+
try {
|
|
125
|
+
await handler.chargeAccount(call.request);
|
|
126
|
+
callback(null, {});
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
logger.error("Error in chargeAccount:", error);
|
|
130
|
+
callback({
|
|
131
|
+
code: grpc.status.INTERNAL,
|
|
132
|
+
message: "Internal server error."
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
},
|
|
136
|
+
getAccountBalance: async (call, callback) => {
|
|
137
|
+
logger.verbose("getAccountBalance called");
|
|
138
|
+
logger.verbose(JSON.stringify(call.request));
|
|
139
|
+
try {
|
|
140
|
+
const balance = await handler.getAccountBalance(call.request);
|
|
141
|
+
callback(null, { balance });
|
|
142
|
+
}
|
|
143
|
+
catch (error) {
|
|
144
|
+
logger.error("Error in getAccountBalance:", error);
|
|
145
|
+
callback({
|
|
146
|
+
code: grpc.status.INTERNAL,
|
|
147
|
+
message: "Internal server error."
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
});
|
|
152
|
+
healthImpl.addToServer(server);
|
|
153
|
+
const bindAddr = `${this.config.bind}:${this.config.port}`;
|
|
154
|
+
server.bindAsync(bindAddr, credentials, async (err, port) => {
|
|
155
|
+
if (err) {
|
|
156
|
+
logger.error("Failed to bind server:", err);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
healthImpl.setStatus("", common_1.GRPC_SERVING_STATUS);
|
|
160
|
+
logger.info(`Authz server started at ${this.config.bind}:${port}`);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
logger.error("Error starting AuthzServer:", err);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
exports.default = AuthzServer;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { AuthzHandler, ChargeAccountRequest, CheckMethodAuthorizedRequest, GetAccountBalanceRequest, VoiceRequest } from "../types";
|
|
2
|
+
declare class DummyAuthzHandler implements AuthzHandler {
|
|
3
|
+
checkSessionAuthorized(request: VoiceRequest): Promise<boolean>;
|
|
4
|
+
checkMethodAuthorized(request: CheckMethodAuthorizedRequest): Promise<boolean>;
|
|
5
|
+
chargeAccount(request: ChargeAccountRequest): Promise<void>;
|
|
6
|
+
getAccountBalance(request: GetAccountBalanceRequest): Promise<number>;
|
|
7
|
+
}
|
|
8
|
+
export { DummyAuthzHandler };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DummyAuthzHandler = void 0;
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (C) 2024 by Fonoster Inc (https://fonoster.com)
|
|
6
|
+
* http://github.com/fonoster/fonoster
|
|
7
|
+
*
|
|
8
|
+
* This file is part of Fonoster
|
|
9
|
+
*
|
|
10
|
+
* Licensed under the MIT License (the "License");
|
|
11
|
+
* you may not use this file except in compliance with
|
|
12
|
+
* the License. You may obtain a copy of the License at
|
|
13
|
+
*
|
|
14
|
+
* https://opensource.org/licenses/MIT
|
|
15
|
+
*
|
|
16
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
18
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
19
|
+
* See the License for the specific language governing permissions and
|
|
20
|
+
* limitations under the License.
|
|
21
|
+
*/
|
|
22
|
+
const logger_1 = require("@fonoster/logger");
|
|
23
|
+
const logger = (0, logger_1.getLogger)({ service: "authz", filePath: __filename });
|
|
24
|
+
class DummyAuthzHandler {
|
|
25
|
+
async checkSessionAuthorized(request) {
|
|
26
|
+
logger.verbose("checkSessionAuthorized called", request);
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
async checkMethodAuthorized(request) {
|
|
30
|
+
logger.verbose("checkMethodAuthorized called", request);
|
|
31
|
+
return false;
|
|
32
|
+
}
|
|
33
|
+
async chargeAccount(request) {
|
|
34
|
+
logger.verbose("chargeAccount called", request);
|
|
35
|
+
}
|
|
36
|
+
async getAccountBalance(request) {
|
|
37
|
+
logger.verbose("getAccountBalance called", request);
|
|
38
|
+
return 20.2;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
exports.DummyAuthzHandler = DummyAuthzHandler;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./AuthzServer";
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
/*
|
|
18
|
+
* Copyright (C) 2024 by Fonoster Inc (https://fonoster.com)
|
|
19
|
+
* http://github.com/fonoster/fonoster
|
|
20
|
+
*
|
|
21
|
+
* This file is part of Fonoster
|
|
22
|
+
*
|
|
23
|
+
* Licensed under the MIT License (the "License");
|
|
24
|
+
* you may not use this file except in compliance with
|
|
25
|
+
* the License. You may obtain a copy of the License at
|
|
26
|
+
*
|
|
27
|
+
* https://opensource.org/licenses/MIT
|
|
28
|
+
*
|
|
29
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
30
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
31
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
32
|
+
* See the License for the specific language governing permissions and
|
|
33
|
+
* limitations under the License.
|
|
34
|
+
*/
|
|
35
|
+
__exportStar(require("./AuthzServer"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
/*
|
|
7
|
+
* Copyright (C) 2024 by Fonoster Inc (https://fonoster.com)
|
|
8
|
+
* http://github.com/fonoster/fonoster
|
|
9
|
+
*
|
|
10
|
+
* This file is part of Fonoster
|
|
11
|
+
*
|
|
12
|
+
* Licensed under the MIT License (the "License");
|
|
13
|
+
* you may not use this file except in compliance with
|
|
14
|
+
* the License. You may obtain a copy of the License at
|
|
15
|
+
*
|
|
16
|
+
* https://opensource.org/licenses/MIT
|
|
17
|
+
*
|
|
18
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
19
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
20
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
21
|
+
* See the License for the specific language governing permissions and
|
|
22
|
+
* limitations under the License.
|
|
23
|
+
*/
|
|
24
|
+
const AuthzServer_1 = __importDefault(require("./AuthzServer"));
|
|
25
|
+
const DummyAuthzHandler_1 = require("./DummyAuthzHandler");
|
|
26
|
+
new AuthzServer_1.default().listen(new DummyAuthzHandler_1.DummyAuthzHandler());
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.serviceDefinition = void 0;
|
|
4
|
+
/*
|
|
5
|
+
* Copyright (C) 2024 by Fonoster Inc (https://fonoster.com)
|
|
6
|
+
* http://github.com/fonoster/fonoster
|
|
7
|
+
*
|
|
8
|
+
* This file is part of Fonoster
|
|
9
|
+
*
|
|
10
|
+
* Licensed under the MIT License (the "License");
|
|
11
|
+
* you may not use this file except in compliance with
|
|
12
|
+
* the License. You may obtain a copy of the License at
|
|
13
|
+
*
|
|
14
|
+
* https://opensource.org/licenses/MIT
|
|
15
|
+
*
|
|
16
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
17
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
18
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
19
|
+
* See the License for the specific language governing permissions and
|
|
20
|
+
* limitations under the License.
|
|
21
|
+
*/
|
|
22
|
+
const common_1 = require("@fonoster/common");
|
|
23
|
+
const serviceDefinition = (0, common_1.createServiceDefinition)({
|
|
24
|
+
serviceName: "Authz",
|
|
25
|
+
pckg: "authz",
|
|
26
|
+
proto: "authz.proto",
|
|
27
|
+
version: "v1beta2"
|
|
28
|
+
});
|
|
29
|
+
exports.serviceDefinition = serviceDefinition;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { VoiceRequest } from "@fonoster/common";
|
|
2
|
+
type ServerConfig = {
|
|
3
|
+
bind?: string;
|
|
4
|
+
port?: number;
|
|
5
|
+
};
|
|
6
|
+
type CheckMethodAuthorizedRequest = {
|
|
7
|
+
accessKeyId: string;
|
|
8
|
+
method: string;
|
|
9
|
+
};
|
|
10
|
+
type ChargeAccountRequest = {
|
|
11
|
+
accessKeyId: string;
|
|
12
|
+
amount: number;
|
|
13
|
+
};
|
|
14
|
+
type GetAccountBalanceRequest = {
|
|
15
|
+
accessKeyId: string;
|
|
16
|
+
};
|
|
17
|
+
type AuthzHandler = {
|
|
18
|
+
checkSessionAuthorized(request: VoiceRequest): Promise<boolean>;
|
|
19
|
+
checkMethodAuthorized(request: CheckMethodAuthorizedRequest): Promise<boolean>;
|
|
20
|
+
chargeAccount(request: ChargeAccountRequest): Promise<void>;
|
|
21
|
+
getAccountBalance(request: GetAccountBalanceRequest): Promise<number>;
|
|
22
|
+
};
|
|
23
|
+
export { ServerConfig, AuthzHandler, VoiceRequest, CheckMethodAuthorizedRequest, ChargeAccountRequest, GetAccountBalanceRequest };
|
package/dist/types.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fonoster/authz",
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "Authorization module for Fonoster",
|
|
5
|
+
"author": "Pedro Sanders <psanders@fonoster.com>",
|
|
6
|
+
"homepage": "https://github.com/fonoster/fonoster#readme",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"main": "dist/index",
|
|
9
|
+
"types": "dist/index",
|
|
10
|
+
"directories": {
|
|
11
|
+
"src": "src",
|
|
12
|
+
"test": "test"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"prebuild": "rimraf ./dist tsconfig.tsbuildinfo",
|
|
16
|
+
"build": "tsc -b tsconfig.json",
|
|
17
|
+
"clean": "rimraf ./dist node_modules tsconfig.tsbuildinfo"
|
|
18
|
+
},
|
|
19
|
+
"bin": {
|
|
20
|
+
"authz": "./dist/server.js"
|
|
21
|
+
},
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@fonoster/common": "^0.8.0",
|
|
30
|
+
"@fonoster/identity": "^0.8.0",
|
|
31
|
+
"@fonoster/logger": "^0.8.0",
|
|
32
|
+
"@grpc/grpc-js": "~1.10.6",
|
|
33
|
+
"deepmerge": "^4.3.1",
|
|
34
|
+
"grpc-health-check": "^2.0.2"
|
|
35
|
+
},
|
|
36
|
+
"repository": {
|
|
37
|
+
"type": "git",
|
|
38
|
+
"url": "git+https://github.com/fonoster/fonoster.git"
|
|
39
|
+
},
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/fonoster/fonoster/issues"
|
|
42
|
+
},
|
|
43
|
+
"gitHead": "9d8a6fc044fe23f4f75356c142d1ca412db5af15"
|
|
44
|
+
}
|