172 lines
4.2 KiB
TypeScript
172 lines
4.2 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import { getToken } from 'src/utility/token';
|
|
import { Repository } from 'typeorm';
|
|
import { AccessEntity } from './access.entity';
|
|
import { IcynetActorEntity } from './icynet.entity';
|
|
import { ZoneEntity } from './zone.entity';
|
|
|
|
@Injectable()
|
|
export class ManagerService {
|
|
constructor(
|
|
@InjectRepository(AccessEntity)
|
|
private access: Repository<AccessEntity>,
|
|
@InjectRepository(ZoneEntity)
|
|
private zone: Repository<ZoneEntity>,
|
|
@InjectRepository(IcynetActorEntity)
|
|
private actors: Repository<IcynetActorEntity>,
|
|
) {}
|
|
|
|
public async getZoneForKey(key: string): Promise<ZoneEntity> {
|
|
const keyData = await this.getKey(key);
|
|
if (
|
|
!keyData ||
|
|
(keyData.expires_at && keyData.expires_at.getTime() < Date.now())
|
|
)
|
|
return null;
|
|
return keyData.zone;
|
|
}
|
|
|
|
public async getKey(key: string): Promise<AccessEntity> {
|
|
return this.access.findOne({
|
|
where: { key },
|
|
relations: ['zone'],
|
|
});
|
|
}
|
|
|
|
public async getZone(zone: string): Promise<ZoneEntity> {
|
|
return this.zone.findOne({
|
|
where: {
|
|
zone,
|
|
},
|
|
});
|
|
}
|
|
|
|
public async getAllKeys(zone: string): Promise<AccessEntity[]> {
|
|
const obj = await this.getZone(zone);
|
|
if (!obj) return [];
|
|
|
|
return this.access.find({
|
|
where: { zone: { id: obj.id } },
|
|
});
|
|
}
|
|
|
|
public async getZonesByIcynetUUID(uuid: string): Promise<ZoneEntity[]> {
|
|
const actor = await this.actors.findOne({
|
|
where: { icynetUUID: uuid },
|
|
});
|
|
|
|
if (!actor) return [];
|
|
|
|
return actor.zones;
|
|
}
|
|
|
|
/**
|
|
* Create a new temporary API key for Icy Network user for their domain.
|
|
* @param icynetUUID Icy Network user UUID
|
|
* @param domain Zone name
|
|
* @returns Access key when authorized
|
|
*/
|
|
public async createIcynetAccessKey(
|
|
icynetUUID: string,
|
|
domain: string,
|
|
): Promise<AccessEntity> {
|
|
const zones = await this.getZonesByIcynetUUID(icynetUUID);
|
|
if (!zones.length) return null;
|
|
|
|
const entry = zones.find((zone) => zone.zone === domain);
|
|
if (!entry) return null;
|
|
|
|
const newObject = {
|
|
key: getToken(),
|
|
zone: entry,
|
|
expires_at: Date.now() + 24 * 60 * 60 * 1000,
|
|
};
|
|
|
|
return this.access.save(newObject);
|
|
}
|
|
|
|
/**
|
|
* Grant access of a zone to an Icy Network user
|
|
* @param icynetUUID Icy Network user UUID
|
|
* @param domain Zone name
|
|
*/
|
|
public async authorizeIcynetUser(
|
|
icynetUUID: string,
|
|
domain: string,
|
|
): Promise<boolean> {
|
|
const zone = await this.getZone(domain);
|
|
if (!zone) return false;
|
|
|
|
const zones = await this.getZonesByIcynetUUID(icynetUUID);
|
|
if (zones.length && zones.some((item) => item.zone === zone.zone)) {
|
|
return false;
|
|
}
|
|
|
|
const actor = await this.actors.findOne({
|
|
where: { icynetUUID },
|
|
});
|
|
|
|
actor.zones = [...zones, zone];
|
|
await this.actors.save(actor);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Remove access of a zone from an Icy Network user
|
|
* @param icynetUUID Icy Network user UUID
|
|
* @param domain Zone name
|
|
*/
|
|
public async revokeIcynetUser(
|
|
icynetUUID: string,
|
|
domain: string,
|
|
): Promise<boolean> {
|
|
const zone = await this.getZone(domain);
|
|
if (!zone) return false;
|
|
|
|
const zones = await this.getZonesByIcynetUUID(icynetUUID);
|
|
if (zones.length || !zones.some((item) => item.zone === zone.zone)) {
|
|
return false;
|
|
}
|
|
|
|
const actor = await this.actors.findOne({
|
|
where: { icynetUUID },
|
|
});
|
|
|
|
actor.zones = actor.zones.filter((item) => item.zone !== zone.zone);
|
|
await this.actors.save(actor);
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Create a new API token for accessing a zone.
|
|
* @param domain Zone to access
|
|
* @returns Access object
|
|
*/
|
|
public async createToken(domain: string): Promise<AccessEntity> {
|
|
const zone = await this.getZone(domain);
|
|
if (!zone) return null;
|
|
|
|
const newObject = {
|
|
key: getToken(),
|
|
zone,
|
|
};
|
|
|
|
return this.access.save(newObject);
|
|
}
|
|
|
|
/**
|
|
* Add a new zone to be managed.
|
|
* @param domain Zone to add
|
|
* @returns Zone object
|
|
*/
|
|
public async addZone(domain: string): Promise<ZoneEntity> {
|
|
const zone = await this.getZone(domain);
|
|
if (zone) return zone;
|
|
|
|
return this.zone.save({
|
|
zone: domain,
|
|
});
|
|
}
|
|
}
|