web/satellite: use edge service URL overrides

This change makes the satellite frontend use edge service URL overrides
if they have been configured for a project.

Resolves #6188
Resolves #6190

Change-Id: I4c8fb3f5f00f450fb8cd139383972ab622234fb0
This commit is contained in:
Jeremy Wharton 2023-08-30 21:34:28 -05:00
parent c8f4f5210d
commit 4f8697568d
4 changed files with 34 additions and 7 deletions

View File

@ -44,6 +44,7 @@ export class ProjectsHttpApi implements ProjectsApi {
result.ownerId, result.ownerId,
false, false,
result.memberCount, result.memberCount,
result.edgeURLOverrides,
); );
} }
@ -80,6 +81,7 @@ export class ProjectsHttpApi implements ProjectsApi {
p.ownerId, p.ownerId,
false, false,
p.memberCount, p.memberCount,
p.edgeURLOverrides,
)); ));
} }
@ -259,6 +261,7 @@ export class ProjectsHttpApi implements ProjectsApi {
p.ownerId, p.ownerId,
false, false,
p.memberCount, p.memberCount,
p.edgeURLOverrides,
)); ));
return new ProjectsPage(projects, page.limit, page.offset, page.pageCount, page.currentPage, page.totalCount); return new ProjectsPage(projects, page.limit, page.offset, page.pageCount, page.currentPage, page.totalCount);

View File

@ -8,6 +8,7 @@ import { useConfigStore } from '@/store/modules/configStore';
import { useProjectsStore } from '@/store/modules/projectsStore'; import { useProjectsStore } from '@/store/modules/projectsStore';
import { useBucketsStore } from '@/store/modules/bucketsStore'; import { useBucketsStore } from '@/store/modules/bucketsStore';
import { AccessGrant, EdgeCredentials } from '@/types/accessGrants'; import { AccessGrant, EdgeCredentials } from '@/types/accessGrants';
import { Project } from '@/types/projects';
const WORKER_ERR_MSG = 'Worker is not defined'; const WORKER_ERR_MSG = 'Worker is not defined';
@ -19,6 +20,16 @@ export function useLinksharing() {
const worker = computed((): Worker | null => agStore.state.accessGrantsWebWorker); const worker = computed((): Worker | null => agStore.state.accessGrantsWebWorker);
const selectedProject = computed<Project>(() => projectsStore.state.selectedProject);
const linksharingURL = computed<string>(() => {
return selectedProject.value.edgeURLOverrides?.internalLinksharing || configStore.state.config.linksharingURL;
});
const publicLinksharingURL = computed<string>(() => {
return selectedProject.value.edgeURLOverrides?.publicLinksharing || configStore.state.config.publicLinksharingURL;
});
async function generateFileOrFolderShareURL(bucketName: string, path: string, isFolder = false): Promise<string> { async function generateFileOrFolderShareURL(bucketName: string, path: string, isFolder = false): Promise<string> {
const fullPath = `${bucketName}/${path}`; const fullPath = `${bucketName}/${path}`;
const type = isFolder ? 'folder' : 'object'; const type = isFolder ? 'folder' : 'object';
@ -33,10 +44,10 @@ export function useLinksharing() {
if (!worker.value) throw new Error(WORKER_ERR_MSG); if (!worker.value) throw new Error(WORKER_ERR_MSG);
const LINK_SHARING_AG_NAME = `${path}_shared-${type}_${new Date().toISOString()}`; const LINK_SHARING_AG_NAME = `${path}_shared-${type}_${new Date().toISOString()}`;
const grant: AccessGrant = await agStore.createAccessGrant(LINK_SHARING_AG_NAME, projectsStore.state.selectedProject.id); const grant: AccessGrant = await agStore.createAccessGrant(LINK_SHARING_AG_NAME, selectedProject.value.id);
const credentials: EdgeCredentials = await generateCredentials(grant.secret, path, null); const credentials: EdgeCredentials = await generateCredentials(grant.secret, path, null);
return `${configStore.state.config.publicLinksharingURL}/${credentials.accessKeyId}/${encodeURIComponent(path.trim())}`; return `${publicLinksharingURL.value}/${credentials.accessKeyId}/${encodeURIComponent(path.trim())}`;
} }
async function generateObjectPreviewAndMapURL(bucketName: string, path: string): Promise<string> { async function generateObjectPreviewAndMapURL(bucketName: string, path: string): Promise<string> {
@ -47,14 +58,14 @@ export function useLinksharing() {
const inOneDay = new Date(now.setDate(now.getDate() + 1)); const inOneDay = new Date(now.setDate(now.getDate() + 1));
const creds: EdgeCredentials = await generateCredentials(bucketsStore.state.apiKey, path, inOneDay); const creds: EdgeCredentials = await generateCredentials(bucketsStore.state.apiKey, path, inOneDay);
return `${configStore.state.config.linksharingURL}/s/${creds.accessKeyId}/${encodeURIComponent(path.trim())}`; return `${linksharingURL.value}/s/${creds.accessKeyId}/${encodeURIComponent(path.trim())}`;
} }
async function generateCredentials(cleanAPIKey: string, path: string, expiration: Date | null): Promise<EdgeCredentials> { async function generateCredentials(cleanAPIKey: string, path: string, expiration: Date | null): Promise<EdgeCredentials> {
if (!worker.value) throw new Error(WORKER_ERR_MSG); if (!worker.value) throw new Error(WORKER_ERR_MSG);
const satelliteNodeURL = configStore.state.config.satelliteNodeURL; const satelliteNodeURL = configStore.state.config.satelliteNodeURL;
const salt = await projectsStore.getProjectSalt(projectsStore.state.selectedProject.id); const salt = await projectsStore.getProjectSalt(selectedProject.value.id);
worker.value.postMessage({ worker.value.postMessage({
'type': 'GenerateAccess', 'type': 'GenerateAccess',
@ -100,7 +111,7 @@ export function useLinksharing() {
throw new Error(data.error); throw new Error(data.error);
} }
return agStore.getEdgeCredentials(data.value, undefined, true); return agStore.getEdgeCredentials(data.value, true);
} }
return { return {

View File

@ -15,6 +15,7 @@ import {
import { SortDirection } from '@/types/common'; import { SortDirection } from '@/types/common';
import { AccessGrantsHttpApi } from '@/api/accessGrants'; import { AccessGrantsHttpApi } from '@/api/accessGrants';
import { useConfigStore } from '@/store/modules/configStore'; import { useConfigStore } from '@/store/modules/configStore';
import { useProjectsStore } from '@/store/modules/projectsStore';
import { DEFAULT_PAGE_LIMIT } from '@/types/pagination'; import { DEFAULT_PAGE_LIMIT } from '@/types/pagination';
class AccessGrantsState { class AccessGrantsState {
@ -41,6 +42,7 @@ export const useAccessGrantsStore = defineStore('accessGrants', () => {
const state = reactive<AccessGrantsState>(new AccessGrantsState()); const state = reactive<AccessGrantsState>(new AccessGrantsState());
const configStore = useConfigStore(); const configStore = useConfigStore();
const projectsStore = useProjectsStore();
async function startWorker(): Promise<void> { async function startWorker(): Promise<void> {
// TODO(vitalii): create an issue here https://github.com/vitejs/vite // TODO(vitalii): create an issue here https://github.com/vitejs/vite
@ -111,8 +113,9 @@ export const useAccessGrantsStore = defineStore('accessGrants', () => {
await api.deleteByNameAndProjectID(name, projectID); await api.deleteByNameAndProjectID(name, projectID);
} }
async function getEdgeCredentials(accessGrant: string, optionalURL?: string, isPublic?: boolean): Promise<EdgeCredentials> { async function getEdgeCredentials(accessGrant: string, isPublic?: boolean): Promise<EdgeCredentials> {
const url = optionalURL || configStore.state.config.gatewayCredentialsRequestURL; const url = projectsStore.state.selectedProject.edgeURLOverrides?.authService
|| configStore.state.config.gatewayCredentialsRequestURL;
const credentials: EdgeCredentials = await api.getGatewayCredentials(accessGrant, url, isPublic); const credentials: EdgeCredentials = await api.getGatewayCredentials(accessGrant, url, isPublic);
state.edgeCredentials = credentials; state.edgeCredentials = credentials;

View File

@ -107,6 +107,7 @@ export class Project {
public ownerId: string = '', public ownerId: string = '',
public isSelected: boolean = false, public isSelected: boolean = false,
public memberCount: number = 0, public memberCount: number = 0,
public edgeURLOverrides?: EdgeURLOverrides,
) {} ) {}
/** /**
@ -118,6 +119,15 @@ export class Project {
} }
} }
/**
* EdgeURLOverrides contains overrides for edge service URLs.
*/
export type EdgeURLOverrides = {
authService?: string;
publicLinksharing?: string;
internalLinksharing?: string;
};
/** /**
* ProjectFields is a type, used for creating and updating project. * ProjectFields is a type, used for creating and updating project.
*/ */