patch..
This commit is contained in:
+5
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE "device_authorizations"
|
||||
ADD COLUMN "registration_reference" TEXT;
|
||||
|
||||
CREATE INDEX "device_authorizations_registration_reference_idx"
|
||||
ON "device_authorizations"("registration_reference");
|
||||
@@ -237,6 +237,7 @@ model DeviceAuthorization {
|
||||
authUserName String? @map("auth_user_name")
|
||||
authUserRole String? @map("auth_user_role")
|
||||
authUserRoles Json? @map("auth_user_roles")
|
||||
registrationReference String? @map("registration_reference")
|
||||
device Json?
|
||||
expiresAt DateTime @map("expires_at") @db.Timestamptz(3)
|
||||
approvedAt DateTime? @map("approved_at") @db.Timestamptz(3)
|
||||
@@ -245,6 +246,7 @@ model DeviceAuthorization {
|
||||
updatedAt DateTime @updatedAt @map("updated_at") @db.Timestamptz(3)
|
||||
|
||||
@@index([status, expiresAt])
|
||||
@@index([registrationReference])
|
||||
@@map("device_authorizations")
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,10 @@ import { IsNotEmpty, IsObject, IsOptional, IsString, ValidateNested } from 'clas
|
||||
import { ProvisioningDeviceDto } from './create-provisioning.dto';
|
||||
|
||||
export class CreateDeviceAuthorizationDto {
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
registrationReference?: string;
|
||||
|
||||
@IsString()
|
||||
@IsOptional()
|
||||
hostname?: string;
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { Body, Controller, Get, Headers, Post, UnauthorizedException } from '@nestjs/common';
|
||||
import { Body, Controller, Get, Headers, Param, Post, UnauthorizedException } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
|
||||
import { CreateProvisioningDto } from './dto/create-provisioning.dto';
|
||||
import { CreateSessionProvisioningDto } from './dto/create-session-provisioning.dto';
|
||||
import {
|
||||
ConsumeDeviceAuthorizationDto,
|
||||
CreateDeviceAuthorizationDto,
|
||||
} from './dto/device-authorization.dto';
|
||||
import { ProvisioningService } from './provisioning.service';
|
||||
import type { ProvisioningResponse } from './provisioning.service';
|
||||
@@ -37,9 +38,11 @@ export class ProvisioningController {
|
||||
@Post('device-authorizations')
|
||||
createDeviceAuthorization(
|
||||
@Headers('authorization') authorization: string | undefined,
|
||||
@Body() body: CreateDeviceAuthorizationDto,
|
||||
) {
|
||||
return this.provisioningService.createDeviceAuthorization(
|
||||
this.getBearerToken(authorization),
|
||||
body,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -66,6 +69,17 @@ export class ProvisioningController {
|
||||
return this.provisioningService.consumeDeviceAuthorization(body);
|
||||
}
|
||||
|
||||
@Get('device-authorizations/registration/:reference')
|
||||
getDeviceAuthorizationByRegistrationReference(
|
||||
@Headers('authorization') authorization: string | undefined,
|
||||
@Param('reference') reference: string,
|
||||
) {
|
||||
return this.provisioningService.getDeviceAuthorizationByRegistrationReference(
|
||||
this.getBearerToken(authorization),
|
||||
reference,
|
||||
);
|
||||
}
|
||||
|
||||
@Post('ssh-keys/lookup')
|
||||
listSshKeys(
|
||||
@Headers('x-lms-gateway-token') token: string | undefined,
|
||||
|
||||
@@ -14,7 +14,10 @@ import { createHash, randomBytes } from 'crypto';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import { CreateProvisioningDto } from './dto/create-provisioning.dto';
|
||||
import { CreateSessionProvisioningDto } from './dto/create-session-provisioning.dto';
|
||||
import { ConsumeDeviceAuthorizationDto } from './dto/device-authorization.dto';
|
||||
import {
|
||||
ConsumeDeviceAuthorizationDto,
|
||||
CreateDeviceAuthorizationDto,
|
||||
} from './dto/device-authorization.dto';
|
||||
|
||||
export type ProvisioningResponse = {
|
||||
installTailscale: boolean;
|
||||
@@ -79,7 +82,10 @@ export class ProvisioningService {
|
||||
return this.createProvisioningForUser(provisioningDto, authUser);
|
||||
}
|
||||
|
||||
async createDeviceAuthorization(accessToken: string | undefined) {
|
||||
async createDeviceAuthorization(
|
||||
accessToken: string | undefined,
|
||||
input: CreateDeviceAuthorizationDto = {},
|
||||
) {
|
||||
const authUser = await this.authenticateAccessToken(accessToken);
|
||||
const expiresInSeconds = Math.max(
|
||||
60,
|
||||
@@ -100,6 +106,7 @@ export class ProvisioningService {
|
||||
authUserName: authUser.name ?? null,
|
||||
authUserRole: authUser.role ?? null,
|
||||
authUserRoles: authUser.roles ? this.cleanJson(authUser.roles) : undefined,
|
||||
registrationReference: this.cleanString(input.registrationReference),
|
||||
expiresAt,
|
||||
approvedAt: new Date(),
|
||||
},
|
||||
@@ -155,6 +162,35 @@ export class ProvisioningService {
|
||||
return { cancelled: result.count > 0 };
|
||||
}
|
||||
|
||||
async getDeviceAuthorizationByRegistrationReference(
|
||||
accessToken: string | undefined,
|
||||
reference: string,
|
||||
) {
|
||||
const authUser = await this.authenticateAccessToken(accessToken);
|
||||
const registrationReference = this.cleanString(reference);
|
||||
if (!registrationReference) {
|
||||
throw new NotFoundException('Device authorization request was not found');
|
||||
}
|
||||
|
||||
const authorization = await this.prisma.deviceAuthorization.findFirst({
|
||||
where: {
|
||||
registrationReference,
|
||||
authUserId: authUser.id,
|
||||
accountEmail: authUser.email,
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
select: {
|
||||
status: true,
|
||||
expiresAt: true,
|
||||
consumedAt: true,
|
||||
accountEmail: true,
|
||||
device: true,
|
||||
},
|
||||
});
|
||||
|
||||
return authorization ?? null;
|
||||
}
|
||||
|
||||
async consumeDeviceAuthorization(body: ConsumeDeviceAuthorizationDto) {
|
||||
const userCode = this.normalizeUserCode(body.userCode);
|
||||
const authorization = await this.prisma.deviceAuthorization.findUnique({
|
||||
@@ -202,7 +238,16 @@ export class ProvisioningService {
|
||||
const provisioning = await this.createProvisioningForUser(body, authUser);
|
||||
await this.prisma.deviceAuthorization.update({
|
||||
where: { id: authorization.id },
|
||||
data: { status: 'CONSUMED', consumedAt: new Date() },
|
||||
data: {
|
||||
status: 'CONSUMED',
|
||||
consumedAt: new Date(),
|
||||
device: this.cleanJson({
|
||||
...(body.device ?? {}),
|
||||
hostname: body.hostname ?? body.device?.hostname ?? null,
|
||||
sshUser: body.sshUser ?? body.device?.sshUser ?? null,
|
||||
workspaceRoot: body.workspaceRoot ?? body.device?.workspaceRoot ?? null,
|
||||
}),
|
||||
},
|
||||
});
|
||||
return provisioning;
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user