Initial LisgloSIPS V2 implementation
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
import { BadRequestException, Inject, Injectable } from '@nestjs/common';
|
||||
import {
|
||||
CUSTOMER_GATEWAY_POLICIES_REPOSITORY,
|
||||
type CreatePolicyInput,
|
||||
type CustomerGatewayPoliciesRepository,
|
||||
type CustomerGatewayPolicySummary,
|
||||
type PolicyMatchMode,
|
||||
type PolicyStatus,
|
||||
type UpdatePolicyInput
|
||||
} from './customer-gateway-policies.repository.js';
|
||||
|
||||
interface CreatePolicyDto {
|
||||
lineGroupId?: unknown;
|
||||
name?: unknown;
|
||||
priority?: unknown;
|
||||
callerMode?: unknown;
|
||||
callerValue?: unknown;
|
||||
calleeMode?: unknown;
|
||||
calleeValue?: unknown;
|
||||
status?: unknown;
|
||||
}
|
||||
|
||||
interface UpdatePolicyDto {
|
||||
lineGroupId?: unknown;
|
||||
name?: unknown;
|
||||
priority?: unknown;
|
||||
callerMode?: unknown;
|
||||
callerValue?: unknown;
|
||||
calleeMode?: unknown;
|
||||
calleeValue?: unknown;
|
||||
status?: unknown;
|
||||
}
|
||||
|
||||
interface ReorderDto {
|
||||
policyIds?: unknown;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class CustomerGatewayPoliciesService {
|
||||
constructor(@Inject(CUSTOMER_GATEWAY_POLICIES_REPOSITORY) private readonly policies: CustomerGatewayPoliciesRepository) {}
|
||||
|
||||
list(gatewayId: string): Promise<CustomerGatewayPolicySummary[]> {
|
||||
return this.policies.list(gatewayId);
|
||||
}
|
||||
|
||||
create(gatewayId: string, body: CreatePolicyDto, actorId?: string): Promise<CustomerGatewayPolicySummary> {
|
||||
const callerMode = body.callerMode === undefined ? 'ANY' : this.matchMode(body.callerMode, 'callerMode');
|
||||
const calleeMode = body.calleeMode === undefined ? 'ANY' : this.matchMode(body.calleeMode, 'calleeMode');
|
||||
const input: CreatePolicyInput = {
|
||||
gatewayId,
|
||||
lineGroupId: this.limitedString(body.lineGroupId, 'lineGroupId', 32),
|
||||
name: this.limitedString(body.name, 'name', 120),
|
||||
priority: body.priority === undefined ? undefined : this.priority(body.priority),
|
||||
callerMode,
|
||||
callerValue: this.matchValue(callerMode, body.callerValue, 'callerValue'),
|
||||
calleeMode,
|
||||
calleeValue: this.matchValue(calleeMode, body.calleeValue, 'calleeValue'),
|
||||
status: body.status === undefined ? 'ENABLED' : this.status(body.status),
|
||||
actorId
|
||||
};
|
||||
return this.policies.create(input);
|
||||
}
|
||||
|
||||
update(policyId: string, body: UpdatePolicyDto, actorId?: string): Promise<CustomerGatewayPolicySummary> {
|
||||
const callerMode = body.callerMode === undefined ? undefined : this.matchMode(body.callerMode, 'callerMode');
|
||||
const calleeMode = body.calleeMode === undefined ? undefined : this.matchMode(body.calleeMode, 'calleeMode');
|
||||
const input: UpdatePolicyInput = {
|
||||
lineGroupId: body.lineGroupId === undefined ? undefined : this.limitedString(body.lineGroupId, 'lineGroupId', 32),
|
||||
name: body.name === undefined ? undefined : this.limitedString(body.name, 'name', 120),
|
||||
priority: body.priority === undefined ? undefined : this.priority(body.priority),
|
||||
callerMode,
|
||||
callerValue: callerMode === undefined ? (body.callerValue === undefined ? undefined : this.nullableString(body.callerValue, 'callerValue', 64)) : this.matchValue(callerMode, body.callerValue, 'callerValue'),
|
||||
calleeMode,
|
||||
calleeValue: calleeMode === undefined ? (body.calleeValue === undefined ? undefined : this.nullableString(body.calleeValue, 'calleeValue', 64)) : this.matchValue(calleeMode, body.calleeValue, 'calleeValue'),
|
||||
status: body.status === undefined ? undefined : this.status(body.status),
|
||||
actorId
|
||||
};
|
||||
return this.policies.update(policyId, input);
|
||||
}
|
||||
|
||||
remove(policyId: string, actorId?: string): Promise<CustomerGatewayPolicySummary> {
|
||||
return this.policies.softDelete(policyId, actorId);
|
||||
}
|
||||
|
||||
reorder(gatewayId: string, body: ReorderDto, actorId?: string): Promise<CustomerGatewayPolicySummary[]> {
|
||||
if (!Array.isArray(body.policyIds) || body.policyIds.length === 0) {
|
||||
throw new BadRequestException({ code: 'POLICY_IDS_INVALID', message: 'policyIds must be a non-empty array.' });
|
||||
}
|
||||
return this.policies.reorder(
|
||||
gatewayId,
|
||||
body.policyIds.map((id) => this.limitedString(id, 'policyIds', 32)),
|
||||
actorId
|
||||
);
|
||||
}
|
||||
|
||||
private limitedString(value: unknown, field: string, maxLength: number): string {
|
||||
if (typeof value !== 'string' || value.trim().length === 0) {
|
||||
throw new BadRequestException({ code: 'VALIDATION_ERROR', message: `${field} is required.` });
|
||||
}
|
||||
const trimmed = value.trim();
|
||||
if (trimmed.length > maxLength) {
|
||||
throw new BadRequestException({ code: 'VALIDATION_ERROR', message: `${field} is too long.` });
|
||||
}
|
||||
return trimmed;
|
||||
}
|
||||
|
||||
private nullableString(value: unknown, field: string, maxLength: number): string | null {
|
||||
if (value === null) {
|
||||
return null;
|
||||
}
|
||||
return this.limitedString(value, field, maxLength);
|
||||
}
|
||||
|
||||
private matchMode(value: unknown, field: string): PolicyMatchMode {
|
||||
if (value !== 'ANY' && value !== 'EQUALS' && value !== 'PREFIX') {
|
||||
throw new BadRequestException({ code: 'MATCH_MODE_INVALID', message: `${field} is invalid.` });
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private matchValue(mode: PolicyMatchMode, value: unknown, field: string): string | null {
|
||||
if (mode === 'ANY') {
|
||||
return null;
|
||||
}
|
||||
const text = this.limitedString(value, field, 64);
|
||||
if (!/^[0-9A-Za-z+*#.-]+$/.test(text)) {
|
||||
throw new BadRequestException({ code: 'MATCH_VALUE_INVALID', message: `${field} contains invalid characters.` });
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private priority(value: unknown): number {
|
||||
if (typeof value !== 'number' || !Number.isInteger(value) || value < 1 || value > 10000) {
|
||||
throw new BadRequestException({ code: 'PRIORITY_INVALID', message: 'priority must be an integer from 1 to 10000.' });
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private status(value: unknown): PolicyStatus {
|
||||
if (value !== 'ENABLED' && value !== 'DISABLED') {
|
||||
throw new BadRequestException({ code: 'STATUS_INVALID', message: 'Status is invalid.' });
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user