@routr/connect 2.0.5-alpha.8 → 2.0.6-alpha.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/dist/errors.d.ts +25 -0
- package/dist/errors.js +79 -0
- package/dist/handlers.d.ts +6 -0
- package/dist/handlers.js +74 -0
- package/dist/router.d.ts +5 -0
- package/dist/router.js +138 -0
- package/dist/runner.js +10 -11
- package/dist/service.js +72 -16
- package/dist/tailor.d.ts +3 -0
- package/dist/tailor.js +28 -0
- package/dist/tracer.d.ts +7 -0
- package/dist/tracer.js +53 -0
- package/dist/types.d.ts +13 -0
- package/dist/types.js +10 -0
- package/dist/utils.d.ts +16 -3
- package/dist/utils.js +132 -12
- package/package.json +14 -6
package/dist/errors.d.ts
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
import { ROUTING_DIRECTION } from "./types";
|
2
|
+
/**
|
3
|
+
* Throw when the API server is unavailable.
|
4
|
+
*/
|
5
|
+
export declare class ServiceUnavailableError extends Error {
|
6
|
+
code: number;
|
7
|
+
/**
|
8
|
+
* Create a new ServiceUnavailableError.
|
9
|
+
*
|
10
|
+
* @param {string} message - The error message
|
11
|
+
*/
|
12
|
+
constructor(message: string);
|
13
|
+
}
|
14
|
+
/**
|
15
|
+
* Throw when the route is not supported.
|
16
|
+
*/
|
17
|
+
export declare class UnsuportedRoutingError extends Error {
|
18
|
+
code: number;
|
19
|
+
/**
|
20
|
+
* Create a new ServiceUnavailableError.
|
21
|
+
*
|
22
|
+
* @param {string} routingDir - The routing direction
|
23
|
+
*/
|
24
|
+
constructor(routingDir: ROUTING_DIRECTION);
|
25
|
+
}
|
package/dist/errors.js
ADDED
@@ -0,0 +1,79 @@
|
|
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 (mod) {
|
19
|
+
if (mod && mod.__esModule) return mod;
|
20
|
+
var result = {};
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
22
|
+
__setModuleDefault(result, mod);
|
23
|
+
return result;
|
24
|
+
};
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
26
|
+
exports.UnsuportedRoutingError = exports.ServiceUnavailableError = void 0;
|
27
|
+
/*
|
28
|
+
* Copyright (C) 2022 by Fonoster Inc (https://fonoster.com)
|
29
|
+
* http://github.com/fonoster/routr
|
30
|
+
*
|
31
|
+
* This file is part of Routr
|
32
|
+
*
|
33
|
+
* Licensed under the MIT License (the "License");
|
34
|
+
* you may not use this file except in compliance with
|
35
|
+
* the License. You may obtain a copy of the License at
|
36
|
+
*
|
37
|
+
* https://opensource.org/licenses/MIT
|
38
|
+
*
|
39
|
+
* Unless required by applicable law or agreed to in writing, software
|
40
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
41
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
42
|
+
* See the License for the specific language governing permissions and
|
43
|
+
* limitations under the License.
|
44
|
+
*/
|
45
|
+
const grpc = __importStar(require("@grpc/grpc-js"));
|
46
|
+
/**
|
47
|
+
* Throw when the API server is unavailable.
|
48
|
+
*/
|
49
|
+
class ServiceUnavailableError extends Error {
|
50
|
+
/**
|
51
|
+
* Create a new ServiceUnavailableError.
|
52
|
+
*
|
53
|
+
* @param {string} message - The error message
|
54
|
+
*/
|
55
|
+
constructor(message) {
|
56
|
+
super(message);
|
57
|
+
this.code = grpc.status.UNAVAILABLE;
|
58
|
+
// Set the prototype explicitly.
|
59
|
+
Object.setPrototypeOf(this, ServiceUnavailableError.prototype);
|
60
|
+
}
|
61
|
+
}
|
62
|
+
exports.ServiceUnavailableError = ServiceUnavailableError;
|
63
|
+
/**
|
64
|
+
* Throw when the route is not supported.
|
65
|
+
*/
|
66
|
+
class UnsuportedRoutingError extends Error {
|
67
|
+
/**
|
68
|
+
* Create a new ServiceUnavailableError.
|
69
|
+
*
|
70
|
+
* @param {string} routingDir - The routing direction
|
71
|
+
*/
|
72
|
+
constructor(routingDir) {
|
73
|
+
super("unsupported routing direction: " + routingDir);
|
74
|
+
this.code = grpc.status.UNKNOWN;
|
75
|
+
// Set the prototype explicitly.
|
76
|
+
Object.setPrototypeOf(this, ServiceUnavailableError.prototype);
|
77
|
+
}
|
78
|
+
}
|
79
|
+
exports.UnsuportedRoutingError = UnsuportedRoutingError;
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import { MessageRequest, Response } from "@routr/processor";
|
2
|
+
import { ILocationService } from "@routr/location/src/types";
|
3
|
+
import { CommonConnect as CC } from "@routr/common";
|
4
|
+
export declare const handleRegister: (location: ILocationService) => (request: MessageRequest, res: Response) => Promise<void>;
|
5
|
+
export declare const handleRegistry: (req: MessageRequest, res: Response) => void;
|
6
|
+
export declare const handleRequest: (location: ILocationService, dataAPI?: CC.DataAPI) => (req: MessageRequest, res: Response) => Promise<void | MessageRequest>;
|
package/dist/handlers.js
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
+
});
|
10
|
+
};
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
12
|
+
exports.handleRequest = exports.handleRegistry = exports.handleRegister = void 0;
|
13
|
+
/*
|
14
|
+
* Copyright (C) 2022 by Fonoster Inc (https://fonoster.com)
|
15
|
+
* http://github.com/fonoster/routr
|
16
|
+
*
|
17
|
+
* This file is part of Routr
|
18
|
+
*
|
19
|
+
* Licensed under the MIT License (the "License")
|
20
|
+
* you may not use this file except in compliance with
|
21
|
+
* the License. You may obtain a copy of the License at
|
22
|
+
*
|
23
|
+
* https://opensource.org/licenses/MIT
|
24
|
+
*
|
25
|
+
* Unless required by applicable law or agreed to in writing, software
|
26
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
27
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
28
|
+
* See the License for the specific language governing permissions and
|
29
|
+
* limitations under the License.
|
30
|
+
*/
|
31
|
+
const location_1 = require("@routr/location");
|
32
|
+
const tailor_1 = require("./tailor");
|
33
|
+
const processor_1 = require("@routr/processor");
|
34
|
+
const function_1 = require("fp-ts/function");
|
35
|
+
const router_1 = require("./router");
|
36
|
+
const common_1 = require("@routr/common");
|
37
|
+
const handleRegister = (location) => {
|
38
|
+
return (request, res) => __awaiter(void 0, void 0, void 0, function* () {
|
39
|
+
yield location.addRoute({
|
40
|
+
aor: processor_1.Target.getTargetAOR(request),
|
41
|
+
route: location_1.Helper.createRoute(request)
|
42
|
+
});
|
43
|
+
res.sendOk();
|
44
|
+
});
|
45
|
+
};
|
46
|
+
exports.handleRegister = handleRegister;
|
47
|
+
// TODO: Needs test
|
48
|
+
const handleRegistry = (req, res) => {
|
49
|
+
const route = processor_1.Helper.createRouteFromLastMessage(req);
|
50
|
+
const newReq = (0, function_1.pipe)(req, processor_1.Alterations.addSelfVia(route), processor_1.Alterations.decreaseMaxForwards, processor_1.Alterations.removeAuthorization, processor_1.Alterations.removeRoutes, processor_1.Alterations.removeXEdgePortRef);
|
51
|
+
res.send(newReq);
|
52
|
+
};
|
53
|
+
exports.handleRegistry = handleRegistry;
|
54
|
+
// TODO: If request has X-Connect-Token then validate the JWT value and continue
|
55
|
+
const handleRequest = (location, dataAPI) => (req, res) => __awaiter(void 0, void 0, void 0, function* () {
|
56
|
+
try {
|
57
|
+
const route = processor_1.Extensions.getHeaderValue(req, common_1.CommonTypes.ExtraHeader.EDGEPORT_REF)
|
58
|
+
? processor_1.Helper.createRouteFromLastMessage(req)
|
59
|
+
: yield (0, router_1.router)(location, dataAPI)(req);
|
60
|
+
if (!route)
|
61
|
+
return res.sendNotFound();
|
62
|
+
// Forward request to peer edgeport
|
63
|
+
if (req.edgePortRef !== route.edgePortRef) {
|
64
|
+
return (0, function_1.pipe)(req, processor_1.Alterations.addSelfVia(route),
|
65
|
+
// The LP address belongs to another edgeport
|
66
|
+
processor_1.Alterations.addRouteToListeningPoint(route), processor_1.Alterations.addXEdgePortRef, processor_1.Alterations.decreaseMaxForwards);
|
67
|
+
}
|
68
|
+
res.send((0, tailor_1.tailor)(route, req));
|
69
|
+
}
|
70
|
+
catch (err) {
|
71
|
+
res.sendError(err);
|
72
|
+
}
|
73
|
+
});
|
74
|
+
exports.handleRequest = handleRequest;
|
package/dist/router.d.ts
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
import { Route } from "@routr/common";
|
2
|
+
import { MessageRequest } from "@routr/processor";
|
3
|
+
import { ILocationService } from "@routr/location";
|
4
|
+
import { CommonConnect as CC } from "@routr/common";
|
5
|
+
export declare function router(location: ILocationService, dataAPI: CC.DataAPI): (req: MessageRequest) => Promise<Route>;
|
package/dist/router.js
ADDED
@@ -0,0 +1,138 @@
|
|
1
|
+
"use strict";
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
|
+
});
|
10
|
+
};
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
12
|
+
exports.router = void 0;
|
13
|
+
/*
|
14
|
+
* Copyright (C) 2022 by Fonoster Inc (https://fonoster.com)
|
15
|
+
* http://github.com/fonoster/routr
|
16
|
+
*
|
17
|
+
* This file is part of Routr
|
18
|
+
*
|
19
|
+
* Licensed under the MIT License (the "License")
|
20
|
+
* you may not use this file except in compliance with
|
21
|
+
* the License. You may obtain a copy of the License at
|
22
|
+
*
|
23
|
+
* https://opensource.org/licenses/MIT
|
24
|
+
*
|
25
|
+
* Unless required by applicable law or agreed to in writing, software
|
26
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
27
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
28
|
+
* See the License for the specific language governing permissions and
|
29
|
+
* limitations under the License.
|
30
|
+
*/
|
31
|
+
const types_1 = require("./types");
|
32
|
+
const utils_1 = require("./utils");
|
33
|
+
const processor_1 = require("@routr/processor");
|
34
|
+
const errors_1 = require("./errors");
|
35
|
+
const location_1 = require("@routr/location");
|
36
|
+
const logger_1 = require("@fonoster/logger");
|
37
|
+
const common_1 = require("@routr/common");
|
38
|
+
const logger = (0, logger_1.getLogger)({ service: "connect", filePath: __filename });
|
39
|
+
const getSIPURI = (uri) => `sip:${uri.user}@${uri.host}`;
|
40
|
+
// eslint-disable-next-line require-jsdoc
|
41
|
+
function router(location, dataAPI) {
|
42
|
+
return (req) => __awaiter(this, void 0, void 0, function* () {
|
43
|
+
const fromURI = req.message.from.address.uri;
|
44
|
+
const requestURI = req.message.requestUri;
|
45
|
+
logger.verbose("routing request from: " +
|
46
|
+
getSIPURI(fromURI) +
|
47
|
+
", to: " +
|
48
|
+
getSIPURI(requestURI), { fromURI: getSIPURI(fromURI), requestURI: getSIPURI(requestURI) });
|
49
|
+
const caller = yield (0, utils_1.findResource)(dataAPI, fromURI.host, fromURI.user);
|
50
|
+
const callee = yield (0, utils_1.findResource)(dataAPI, requestURI.host, requestURI.user);
|
51
|
+
const routingDir = (0, utils_1.getRoutingDirection)(caller, callee);
|
52
|
+
switch (routingDir) {
|
53
|
+
case types_1.ROUTING_DIRECTION.AGENT_TO_PSTN:
|
54
|
+
return yield toPSTN(dataAPI, req, caller);
|
55
|
+
case types_1.ROUTING_DIRECTION.AGENT_TO_AGENT:
|
56
|
+
return agentToAgent(location, req);
|
57
|
+
case types_1.ROUTING_DIRECTION.FROM_PSTN:
|
58
|
+
return yield fromPSTN(location, dataAPI, callee);
|
59
|
+
default:
|
60
|
+
throw new errors_1.UnsuportedRoutingError(routingDir);
|
61
|
+
}
|
62
|
+
});
|
63
|
+
}
|
64
|
+
exports.router = router;
|
65
|
+
// eslint-disable-next-line require-jsdoc
|
66
|
+
function agentToAgent(location, req) {
|
67
|
+
return __awaiter(this, void 0, void 0, function* () {
|
68
|
+
return (yield location.findRoutes({ aor: processor_1.Target.getTargetAOR(req) }))[0];
|
69
|
+
});
|
70
|
+
}
|
71
|
+
/**
|
72
|
+
* From PSTN routing.
|
73
|
+
*
|
74
|
+
* @param {ILocationService} location - Location service
|
75
|
+
* @param {uknown} _
|
76
|
+
* @param {Resource} callee - The callee
|
77
|
+
* @return {Promise<Route>}
|
78
|
+
*/
|
79
|
+
function fromPSTN(location, _, callee) {
|
80
|
+
var _a;
|
81
|
+
return __awaiter(this, void 0, void 0, function* () {
|
82
|
+
const route = (yield location.findRoutes({
|
83
|
+
aor: callee.spec.location.aorLink
|
84
|
+
}))[0];
|
85
|
+
if (!route) {
|
86
|
+
throw new location_1.NotRoutesFoundForAOR(callee.spec.location.aorLink);
|
87
|
+
}
|
88
|
+
if (!route.headers)
|
89
|
+
route.headers = [];
|
90
|
+
(_a = callee.spec.location.props) === null || _a === void 0 ? void 0 : _a.forEach((prop) => {
|
91
|
+
const p = {
|
92
|
+
name: prop.name,
|
93
|
+
value: prop.value,
|
94
|
+
action: common_1.CommonTypes.HeaderModifierAction.ADD
|
95
|
+
};
|
96
|
+
route.headers.push(p);
|
97
|
+
});
|
98
|
+
return route;
|
99
|
+
});
|
100
|
+
}
|
101
|
+
// eslint-disable-next-line require-jsdoc
|
102
|
+
function toPSTN(dataAPI, req, caller) {
|
103
|
+
var _a;
|
104
|
+
return __awaiter(this, void 0, void 0, function* () {
|
105
|
+
const domain = yield dataAPI.get(caller.spec.domainRef);
|
106
|
+
const number = yield dataAPI.get((_a = domain.spec.context.egressPolicy) === null || _a === void 0 ? void 0 : _a.numberRef);
|
107
|
+
const trunk = yield dataAPI.get(number === null || number === void 0 ? void 0 : number.spec.trunkRef);
|
108
|
+
if (!domain.spec.context.egressPolicy) {
|
109
|
+
// TODO: Create custom error
|
110
|
+
throw new Error("no egress policy found for Domain ref" + domain.metadata.ref);
|
111
|
+
}
|
112
|
+
if (!trunk) {
|
113
|
+
// TODO: Create custom error
|
114
|
+
throw new Error("no trunk associated with Number ref: " + number.metadata.ref);
|
115
|
+
}
|
116
|
+
const uri = (0, utils_1.getTrunkURI)(trunk);
|
117
|
+
return {
|
118
|
+
user: uri.user,
|
119
|
+
host: uri.host,
|
120
|
+
port: uri.port,
|
121
|
+
transport: uri.transport,
|
122
|
+
edgePortRef: req.edgePortRef,
|
123
|
+
listeningPoint: req.listeningPoint,
|
124
|
+
headers: [
|
125
|
+
{
|
126
|
+
name: "Privacy",
|
127
|
+
value: caller.spec.privacy === common_1.CommonTypes.Privacy.PRIVATE
|
128
|
+
? common_1.CommonTypes.Privacy.PRIVATE
|
129
|
+
: common_1.CommonTypes.Privacy.NONE,
|
130
|
+
action: common_1.CommonTypes.HeaderModifierAction.ADD
|
131
|
+
},
|
132
|
+
(0, utils_1.createRemotePartyId)(trunk, number),
|
133
|
+
(0, utils_1.createPAssertedIdentity)(req, trunk, number),
|
134
|
+
yield (0, utils_1.createTrunkAuthentication)(dataAPI, trunk)
|
135
|
+
]
|
136
|
+
};
|
137
|
+
});
|
138
|
+
}
|
package/dist/runner.js
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
4
4
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
5
5
|
};
|
6
|
+
var _a;
|
6
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
7
8
|
/*
|
8
9
|
* Copyright (C) 2022 by Fonoster Inc (https://fonoster.com)
|
@@ -22,15 +23,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
22
23
|
* See the License for the specific language governing permissions and
|
23
24
|
* limitations under the License.
|
24
25
|
*/
|
25
|
-
|
26
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
27
|
+
require("./tracer").init("dispatcher");
|
26
28
|
const service_1 = __importDefault(require("./service"));
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
logger_1.default.error("environment variable LOCATION_ADDR is required but was not found");
|
35
|
-
process.exit(1);
|
36
|
-
}
|
29
|
+
const common_1 = require("@routr/common");
|
30
|
+
common_1.Assertions.assertEnvsAreSet(["LOCATION_ADDR", "API_ADDR"]);
|
31
|
+
(0, service_1.default)({
|
32
|
+
bindAddr: (_a = process.env.BIND_ADDR) !== null && _a !== void 0 ? _a : "0.0.0.0:51904",
|
33
|
+
locationAddr: process.env.LOCATION_ADDR,
|
34
|
+
apiAddr: process.env.API_ADDR
|
35
|
+
});
|
package/dist/service.js
CHANGED
@@ -1,4 +1,27 @@
|
|
1
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 (mod) {
|
19
|
+
if (mod && mod.__esModule) return mod;
|
20
|
+
var result = {};
|
21
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
22
|
+
__setModuleDefault(result, mod);
|
23
|
+
return result;
|
24
|
+
};
|
2
25
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
3
26
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
4
27
|
return new (P || (P = Promise))(function (resolve, reject) {
|
@@ -8,33 +31,66 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
8
31
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
9
32
|
});
|
10
33
|
};
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
13
|
-
};
|
14
34
|
Object.defineProperty(exports, "__esModule", { value: true });
|
35
|
+
const common_1 = require("@routr/common");
|
15
36
|
const location_1 = require("@routr/location");
|
16
|
-
const
|
17
|
-
const processor_1 =
|
18
|
-
const
|
37
|
+
const handlers_1 = require("./handlers");
|
38
|
+
const processor_1 = __importStar(require("@routr/processor"));
|
39
|
+
const common_2 = require("@routr/common");
|
40
|
+
const tailor_1 = require("./tailor");
|
41
|
+
const logger_1 = require("@fonoster/logger");
|
42
|
+
const logger = (0, logger_1.getLogger)({ service: "connect", filePath: __filename });
|
43
|
+
// eslint-disable-next-line require-jsdoc
|
19
44
|
function ConnectProcessor(config) {
|
20
45
|
const { bindAddr, locationAddr } = config;
|
21
46
|
const location = new location_1.LocationClient({ addr: locationAddr });
|
22
|
-
new processor_1.default({ bindAddr, name: "connect" })
|
23
|
-
.
|
24
|
-
|
47
|
+
new processor_1.default({ bindAddr, name: "connect" }).listen((req, res) => __awaiter(this, void 0, void 0, function* () {
|
48
|
+
logger.verbose("connect processor received new request", {
|
49
|
+
ref: req.ref,
|
50
|
+
method: req.method,
|
51
|
+
type: req.message.messageType === common_2.CommonTypes.MessageType.RESPONSE
|
52
|
+
? "(response)"
|
53
|
+
: "(request)",
|
54
|
+
edgePort: req.edgePortRef
|
55
|
+
});
|
56
|
+
logger.silly(JSON.stringify(req, null, " "));
|
57
|
+
// Check if is response and simply forwards to endpoint
|
58
|
+
if (processor_1.Helper.isTypeResponse(req)) {
|
59
|
+
// Remove the proxy via before forwarding response
|
60
|
+
return res.send(processor_1.Alterations.removeTopVia(req));
|
61
|
+
}
|
25
62
|
switch (req.method.toString()) {
|
26
|
-
case
|
27
|
-
case
|
28
|
-
case
|
63
|
+
case common_1.Method.PUBLISH:
|
64
|
+
case common_1.Method.NOTIFY:
|
65
|
+
case common_1.Method.SUBSCRIBE:
|
29
66
|
res.sendMethodNotAllowed();
|
30
67
|
break;
|
31
|
-
case
|
32
|
-
|
68
|
+
case common_1.Method.CANCEL:
|
69
|
+
// eslint-disable-next-line no-case-declarations
|
70
|
+
const route = (yield location.findRoutes({ aor: processor_1.Target.getTargetAOR(req) }))[0];
|
71
|
+
if (route) {
|
72
|
+
res.sendOk([
|
73
|
+
{
|
74
|
+
name: common_2.CommonTypes.ExtraHeader.REQUEST_URI,
|
75
|
+
value: `${route === null || route === void 0 ? void 0 : route.user},${route.host},${route.port},${route.transport}`
|
76
|
+
}
|
77
|
+
]);
|
78
|
+
}
|
79
|
+
break;
|
80
|
+
case common_1.Method.REGISTER:
|
81
|
+
if (processor_1.Extensions.getHeaderValue(req, common_2.CommonTypes.ExtraHeader.GATEWAY_AUTH)) {
|
82
|
+
(0, handlers_1.handleRegistry)(req, res);
|
83
|
+
}
|
84
|
+
else {
|
85
|
+
(0, handlers_1.handleRegister)(location)(req, res);
|
86
|
+
}
|
33
87
|
break;
|
34
|
-
case
|
88
|
+
case common_1.Method.BYE:
|
89
|
+
case common_1.Method.ACK:
|
90
|
+
res.send((0, tailor_1.tailor)(processor_1.Helper.createRouteFromLastMessage(req), req));
|
35
91
|
break;
|
36
92
|
default:
|
37
|
-
|
93
|
+
yield (0, handlers_1.handleRequest)(location, common_2.CommonConnect.dataAPI(config.apiAddr))(req, res);
|
38
94
|
}
|
39
95
|
}));
|
40
96
|
}
|
package/dist/tailor.d.ts
ADDED
package/dist/tailor.js
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
"use strict";
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.tailor = void 0;
|
4
|
+
/*
|
5
|
+
* Copyright (C) 2022 by Fonoster Inc (https://fonoster.com)
|
6
|
+
* http://github.com/fonoster/routr
|
7
|
+
*
|
8
|
+
* This file is part of Routr
|
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 processor_1 = require("@routr/processor");
|
23
|
+
const function_1 = require("fp-ts/function");
|
24
|
+
// Q: Shoukd we add support for strict routing?
|
25
|
+
const tailor = (route, req) => (0, function_1.pipe)(req, processor_1.Alterations.addSelfVia(route), processor_1.Alterations.applyXHeaders(route), processor_1.Alterations.addRoute(route), processor_1.Alterations.addSelfRecordRoute, processor_1.Alterations.decreaseMaxForwards, processor_1.Alterations.removeAuthorization, processor_1.Alterations.removeRoutes, processor_1.Alterations.removeXEdgePortRef
|
26
|
+
// Add updateContact for SIP.js support
|
27
|
+
);
|
28
|
+
exports.tailor = tailor;
|
package/dist/tracer.d.ts
ADDED
package/dist/tracer.js
ADDED
@@ -0,0 +1,53 @@
|
|
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
|
+
exports.init = void 0;
|
7
|
+
/*
|
8
|
+
* Copyright (C) 2022 by Fonoster Inc (https://fonoster.com)
|
9
|
+
* http://github.com/fonoster/routr
|
10
|
+
*
|
11
|
+
* This file is part of Routr
|
12
|
+
*
|
13
|
+
* Licensed under the MIT License (the "License")
|
14
|
+
* you may not use this file except in compliance with
|
15
|
+
* the License. You may obtain a copy of the License at
|
16
|
+
*
|
17
|
+
* https://opensource.org/licenses/MIT
|
18
|
+
*
|
19
|
+
* Unless required by applicable law or agreed to in writing, software
|
20
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
21
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
22
|
+
* See the License for the specific language governing permissions and
|
23
|
+
* limitations under the License.
|
24
|
+
*/
|
25
|
+
const api_1 = __importDefault(require("@opentelemetry/api"));
|
26
|
+
const instrumentation_1 = require("@opentelemetry/instrumentation");
|
27
|
+
const sdk_trace_node_1 = require("@opentelemetry/sdk-trace-node");
|
28
|
+
const resources_1 = require("@opentelemetry/resources");
|
29
|
+
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
|
30
|
+
const sdk_trace_base_1 = require("@opentelemetry/sdk-trace-base");
|
31
|
+
const exporter_jaeger_1 = require("@opentelemetry/exporter-jaeger");
|
32
|
+
const instrumentation_grpc_1 = require("@opentelemetry/instrumentation-grpc");
|
33
|
+
/**
|
34
|
+
* This function registers the instrumentations for the service.
|
35
|
+
*
|
36
|
+
* @param {string} serviceName - The name of the service.
|
37
|
+
* @return {Tracer} The tracer object.
|
38
|
+
*/
|
39
|
+
function init(serviceName) {
|
40
|
+
const provider = new sdk_trace_node_1.NodeTracerProvider({
|
41
|
+
resource: new resources_1.Resource({
|
42
|
+
[semantic_conventions_1.SemanticResourceAttributes.SERVICE_NAME]: serviceName
|
43
|
+
})
|
44
|
+
});
|
45
|
+
const exporter = new exporter_jaeger_1.JaegerExporter();
|
46
|
+
provider.addSpanProcessor(new sdk_trace_base_1.SimpleSpanProcessor(exporter));
|
47
|
+
provider.register();
|
48
|
+
(0, instrumentation_1.registerInstrumentations)({
|
49
|
+
instrumentations: [new instrumentation_grpc_1.GrpcInstrumentation()]
|
50
|
+
});
|
51
|
+
return api_1.default.trace.getTracer("routr-tracer");
|
52
|
+
}
|
53
|
+
exports.init = init;
|
package/dist/types.d.ts
CHANGED
@@ -1,4 +1,17 @@
|
|
1
|
+
import { HeaderModifier } from "@routr/common";
|
2
|
+
export declare enum ROUTING_DIRECTION {
|
3
|
+
FROM_PSTN = "from-pstn",
|
4
|
+
AGENT_TO_AGENT = "agent-to-agent",
|
5
|
+
AGENT_TO_PSTN = "agent-to-pstn",
|
6
|
+
PEER_TO_AGENT = "peer-to-agent",
|
7
|
+
PEER_TO_PSTN = "peer-to-pstn",
|
8
|
+
UNKNOWN = "unknown"
|
9
|
+
}
|
1
10
|
export interface ConnectProcessorConfig {
|
2
11
|
bindAddr: string;
|
3
12
|
locationAddr: string;
|
13
|
+
apiAddr: string;
|
14
|
+
}
|
15
|
+
export interface ConnectObject {
|
16
|
+
headers?: HeaderModifier[];
|
4
17
|
}
|
package/dist/types.js
CHANGED
@@ -1,2 +1,12 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
+
exports.ROUTING_DIRECTION = void 0;
|
4
|
+
var ROUTING_DIRECTION;
|
5
|
+
(function (ROUTING_DIRECTION) {
|
6
|
+
ROUTING_DIRECTION["FROM_PSTN"] = "from-pstn";
|
7
|
+
ROUTING_DIRECTION["AGENT_TO_AGENT"] = "agent-to-agent";
|
8
|
+
ROUTING_DIRECTION["AGENT_TO_PSTN"] = "agent-to-pstn";
|
9
|
+
ROUTING_DIRECTION["PEER_TO_AGENT"] = "peer-to-agent";
|
10
|
+
ROUTING_DIRECTION["PEER_TO_PSTN"] = "peer-to-pstn";
|
11
|
+
ROUTING_DIRECTION["UNKNOWN"] = "unknown";
|
12
|
+
})(ROUTING_DIRECTION = exports.ROUTING_DIRECTION || (exports.ROUTING_DIRECTION = {}));
|
package/dist/utils.d.ts
CHANGED
@@ -1,3 +1,16 @@
|
|
1
|
-
import { MessageRequest } from "@routr/common";
|
2
|
-
import {
|
3
|
-
|
1
|
+
import { HeaderModifier, MessageRequest, Transport } from "@routr/common";
|
2
|
+
import { CommonConnect as CC } from "@routr/common";
|
3
|
+
import { ROUTING_DIRECTION } from "./types";
|
4
|
+
export declare const isKind: (res: CC.Resource, kind: CC.KIND) => boolean;
|
5
|
+
export declare const findDomain: (dataAPI: CC.DataAPI, domainUri: string) => Promise<CC.Resource>;
|
6
|
+
export declare const findResource: (dataAPI: CC.DataAPI, domainUri: string, userpart: string) => Promise<CC.Resource>;
|
7
|
+
export declare const getRoutingDirection: (caller: CC.Resource, callee: CC.Resource) => ROUTING_DIRECTION;
|
8
|
+
export declare const createPAssertedIdentity: (req: MessageRequest, trunk: CC.Resource, number: CC.Resource) => HeaderModifier;
|
9
|
+
export declare const createRemotePartyId: (trunk: CC.Resource, number: CC.Resource) => HeaderModifier;
|
10
|
+
export declare const createTrunkAuthentication: (dataAPI: CC.DataAPI, trunk: CC.Resource) => Promise<HeaderModifier>;
|
11
|
+
export declare const getTrunkURI: (trunk: CC.Resource) => {
|
12
|
+
host: string;
|
13
|
+
port: number;
|
14
|
+
user: string;
|
15
|
+
transport: Transport;
|
16
|
+
};
|
package/dist/utils.js
CHANGED
@@ -9,16 +9,136 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
9
9
|
});
|
10
10
|
};
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
12
|
-
exports.
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
12
|
+
exports.getTrunkURI = exports.createTrunkAuthentication = exports.createRemotePartyId = exports.createPAssertedIdentity = exports.getRoutingDirection = exports.findResource = exports.findDomain = exports.isKind = void 0;
|
13
|
+
/*
|
14
|
+
* Copyright (C) 2022 by Fonoster Inc (https://fonoster.com)
|
15
|
+
* http://github.com/fonoster/routr
|
16
|
+
*
|
17
|
+
* This file is part of Routr
|
18
|
+
*
|
19
|
+
* Licensed under the MIT License (the "License")
|
20
|
+
* you may not use this file except in compliance with
|
21
|
+
* the License. You may obtain a copy of the License at
|
22
|
+
*
|
23
|
+
* https://opensource.org/licenses/MIT
|
24
|
+
*
|
25
|
+
* Unless required by applicable law or agreed to in writing, software
|
26
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
27
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
28
|
+
* See the License for the specific language governing permissions and
|
29
|
+
* limitations under the License.
|
30
|
+
*/
|
31
|
+
const common_1 = require("@routr/common");
|
32
|
+
const common_2 = require("@routr/common");
|
33
|
+
const types_1 = require("./types");
|
34
|
+
const isKind = (res, kind) => {
|
35
|
+
if (res == null && kind === common_2.CommonConnect.KIND.UNKNOWN) {
|
36
|
+
return true;
|
37
|
+
}
|
38
|
+
return (res === null || res === void 0 ? void 0 : res.kind.toLowerCase()) === kind;
|
39
|
+
};
|
40
|
+
exports.isKind = isKind;
|
41
|
+
const findDomain = (dataAPI, domainUri) => __awaiter(void 0, void 0, void 0, function* () {
|
42
|
+
return (yield dataAPI.findBy({
|
43
|
+
kind: common_2.CommonConnect.KIND.DOMAIN,
|
44
|
+
criteria: common_2.CommonConnect.FindCriteria.FIND_DOMAIN_BY_DOMAINURI,
|
45
|
+
parameters: {
|
46
|
+
domainUri
|
47
|
+
}
|
48
|
+
}))[0];
|
49
|
+
});
|
50
|
+
exports.findDomain = findDomain;
|
51
|
+
const findResource = (dataAPI, domainUri, userpart) => __awaiter(void 0, void 0, void 0, function* () {
|
52
|
+
const domain = yield (0, exports.findDomain)(dataAPI, domainUri);
|
53
|
+
// TODO: Fix jsonpath not working for logical AND and OR
|
54
|
+
let res = (yield dataAPI.findBy({
|
55
|
+
kind: common_2.CommonConnect.KIND.NUMBER,
|
56
|
+
criteria: common_2.CommonConnect.FindCriteria.FIND_NUMBER_BY_TELURL,
|
57
|
+
parameters: {
|
58
|
+
telUrl: `tel:${userpart}`
|
59
|
+
}
|
60
|
+
}))[0];
|
61
|
+
res =
|
62
|
+
res == null
|
63
|
+
? (yield dataAPI.findBy({
|
64
|
+
kind: common_2.CommonConnect.KIND.AGENT,
|
65
|
+
criteria: common_2.CommonConnect.FindCriteria.FIND_AGENT_BY_USERNAME,
|
66
|
+
parameters: {
|
67
|
+
username: userpart
|
68
|
+
}
|
69
|
+
}))[0]
|
70
|
+
: res;
|
71
|
+
if ((0, exports.isKind)(res, common_2.CommonConnect.KIND.AGENT) &&
|
72
|
+
res.spec.domainRef != (domain === null || domain === void 0 ? void 0 : domain.metadata.ref)) {
|
73
|
+
// Not in the same domain
|
74
|
+
return null;
|
75
|
+
}
|
76
|
+
return res;
|
77
|
+
});
|
78
|
+
exports.findResource = findResource;
|
79
|
+
const getRoutingDirection = (caller, callee) => {
|
80
|
+
if ((0, exports.isKind)(caller, common_2.CommonConnect.KIND.AGENT) && (0, exports.isKind)(callee, common_2.CommonConnect.KIND.AGENT)) {
|
81
|
+
return types_1.ROUTING_DIRECTION.AGENT_TO_AGENT;
|
82
|
+
}
|
83
|
+
if ((0, exports.isKind)(caller, common_2.CommonConnect.KIND.AGENT) && (0, exports.isKind)(callee, common_2.CommonConnect.KIND.UNKNOWN)) {
|
84
|
+
return types_1.ROUTING_DIRECTION.AGENT_TO_PSTN;
|
85
|
+
}
|
86
|
+
if ((0, exports.isKind)(caller, common_2.CommonConnect.KIND.PEER) && (0, exports.isKind)(callee, common_2.CommonConnect.KIND.AGENT)) {
|
87
|
+
return types_1.ROUTING_DIRECTION.PEER_TO_AGENT;
|
88
|
+
}
|
89
|
+
// All we know is that the Number is managed by this instance of Routr
|
90
|
+
if ((0, exports.isKind)(callee, common_2.CommonConnect.KIND.NUMBER)) {
|
91
|
+
return types_1.ROUTING_DIRECTION.FROM_PSTN;
|
92
|
+
}
|
93
|
+
if ((0, exports.isKind)(caller, common_2.CommonConnect.KIND.PEER) && (0, exports.isKind)(callee, common_2.CommonConnect.KIND.UNKNOWN)) {
|
94
|
+
return types_1.ROUTING_DIRECTION.PEER_TO_PSTN;
|
95
|
+
}
|
96
|
+
return types_1.ROUTING_DIRECTION.UNKNOWN;
|
97
|
+
};
|
98
|
+
exports.getRoutingDirection = getRoutingDirection;
|
99
|
+
const createPAssertedIdentity = (req, trunk, number) => {
|
100
|
+
const displayName = req.message.from.address.displayName;
|
101
|
+
const remoteNumber = number.spec.location.telUrl.split(":")[1];
|
102
|
+
const trunkHost = (0, exports.getTrunkURI)(trunk).host;
|
103
|
+
return {
|
104
|
+
name: "P-Asserted-Identity",
|
105
|
+
value: displayName
|
106
|
+
? `"${displayName}" <sip:${remoteNumber}@${trunkHost};user=phone>`
|
107
|
+
: `<sip:${remoteNumber}@${trunkHost};user=phone>`,
|
108
|
+
action: common_2.CommonTypes.HeaderModifierAction.ADD
|
109
|
+
};
|
110
|
+
};
|
111
|
+
exports.createPAssertedIdentity = createPAssertedIdentity;
|
112
|
+
const createRemotePartyId = (trunk, number) => {
|
113
|
+
const remoteNumber = number.spec.location.telUrl.split(":")[1];
|
114
|
+
const trunkHost = (0, exports.getTrunkURI)(trunk).host;
|
115
|
+
return {
|
116
|
+
name: "Remote-Party-ID",
|
117
|
+
value: `<sip:${remoteNumber}@${trunkHost}>;screen=yes;party=calling`,
|
118
|
+
action: common_2.CommonTypes.HeaderModifierAction.ADD
|
119
|
+
};
|
120
|
+
};
|
121
|
+
exports.createRemotePartyId = createRemotePartyId;
|
122
|
+
const createTrunkAuthentication = (dataAPI, trunk) => __awaiter(void 0, void 0, void 0, function* () {
|
123
|
+
const credentials = yield dataAPI.get(trunk.spec.outbound.credentialsRef);
|
124
|
+
return {
|
125
|
+
name: common_2.CommonTypes.ExtraHeader.GATEWAY_AUTH,
|
126
|
+
value: Buffer.from(`${credentials.spec.credentials.username}:${credentials.spec.credentials.password}`).toString("base64"),
|
127
|
+
action: common_2.CommonTypes.HeaderModifierAction.ADD
|
128
|
+
};
|
129
|
+
});
|
130
|
+
exports.createTrunkAuthentication = createTrunkAuthentication;
|
131
|
+
const getTrunkURI = (trunk) => {
|
132
|
+
var _a;
|
133
|
+
const { user, host, port, transport } = (_a = trunk.spec.outbound) === null || _a === void 0 ? void 0 : _a.uris[0].uri;
|
134
|
+
const t = !transport
|
135
|
+
? common_1.Transport.UDP
|
136
|
+
: Object.keys(common_1.Transport)[Object.values(common_1.Transport).indexOf(transport.toUpperCase())];
|
137
|
+
return {
|
138
|
+
user,
|
139
|
+
host,
|
140
|
+
port: port !== null && port !== void 0 ? port : 5060,
|
141
|
+
transport: t
|
142
|
+
};
|
23
143
|
};
|
24
|
-
exports.
|
144
|
+
exports.getTrunkURI = getTrunkURI;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@routr/connect",
|
3
|
-
"version": "2.0.
|
3
|
+
"version": "2.0.6-alpha.0",
|
4
4
|
"description": "Default processor",
|
5
5
|
"author": "Pedro Sanders <psanders@fonoster.com>",
|
6
6
|
"homepage": "https://github.com/fonoster/routr#readme",
|
@@ -19,10 +19,18 @@
|
|
19
19
|
"run_connect": "dist/runner.js"
|
20
20
|
},
|
21
21
|
"dependencies": {
|
22
|
-
"@fonoster/logger": "
|
23
|
-
"@
|
24
|
-
"@
|
25
|
-
"@
|
22
|
+
"@fonoster/logger": "0.3.17-alpha.2",
|
23
|
+
"@opentelemetry/api": "^1.0.4",
|
24
|
+
"@opentelemetry/exporter-jaeger": "^1.0.4",
|
25
|
+
"@opentelemetry/instrumentation": "^0.27.0",
|
26
|
+
"@opentelemetry/instrumentation-grpc": "^0.27.0",
|
27
|
+
"@opentelemetry/resources": "^1.0.4",
|
28
|
+
"@opentelemetry/sdk-trace-base": "^1.0.4",
|
29
|
+
"@opentelemetry/sdk-trace-node": "^1.0.4",
|
30
|
+
"@opentelemetry/semantic-conventions": "^1.0.4",
|
31
|
+
"@routr/common": "^2.0.6-alpha.0",
|
32
|
+
"@routr/location": "^2.0.6-alpha.0",
|
33
|
+
"@routr/processor": "^2.0.6-alpha.0"
|
26
34
|
},
|
27
35
|
"files": [
|
28
36
|
"dist"
|
@@ -37,5 +45,5 @@
|
|
37
45
|
"bugs": {
|
38
46
|
"url": "https://github.com/fonoster/routr/issues"
|
39
47
|
},
|
40
|
-
"gitHead": "
|
48
|
+
"gitHead": "0829f7e9b5b3ebba7eb984da5436d7c07689d776"
|
41
49
|
}
|