-
Notifications
You must be signed in to change notification settings - Fork 195
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add integration with: Sharepoint #693
Changes from 8 commits
7102605
773227f
a68dc6d
9252f51
5ad0523
091e72f
74fac19
4409e9d
b938345
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -538,6 +538,7 @@ export class CoreSyncService { | |
try { | ||
await task(); | ||
} catch (error) { | ||
console.log(error); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider removing Using |
||
this.logger.error(`File Storage Task failed: ${error.message}`, error); | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,5 @@ | ||
import { | ||
BoxSharedLinkInput, | ||
BoxSharedLinkOutput, | ||
} from '@filestorage/sharedlink/services/box/types'; | ||
/* INPUT */ | ||
|
||
import { | ||
OnedriveSharedLinkInput, | ||
OnedriveSharedLinkOutput, | ||
|
@@ -37,7 +35,40 @@ import { | |
OnedriveDriveOutput, | ||
} from '@filestorage/drive/services/onedrive/types'; | ||
|
||
/* INPUT */ | ||
import { | ||
SharepointSharedLinkInput, | ||
SharepointSharedLinkOutput, | ||
} from '@filestorage/sharedlink/services/sharepoint/types'; | ||
|
||
import { | ||
SharepointPermissionInput, | ||
SharepointPermissionOutput, | ||
} from '@filestorage/permission/services/sharepoint/types'; | ||
|
||
import { | ||
SharepointGroupInput, | ||
SharepointGroupOutput, | ||
} from '@filestorage/group/services/sharepoint/types'; | ||
|
||
import { | ||
SharepointUserInput, | ||
SharepointUserOutput, | ||
} from '@filestorage/user/services/sharepoint/types'; | ||
|
||
import { | ||
SharepointFolderInput, | ||
SharepointFolderOutput, | ||
} from '@filestorage/folder/services/sharepoint/types'; | ||
|
||
import { | ||
SharepointFileInput, | ||
SharepointFileOutput, | ||
} from '@filestorage/file/services/sharepoint/types'; | ||
|
||
import { | ||
SharepointDriveInput, | ||
SharepointDriveOutput, | ||
} from '@filestorage/drive/services/sharepoint/types'; | ||
|
||
import { | ||
BoxFileInput, | ||
|
@@ -55,27 +86,49 @@ import { | |
BoxUserInput, | ||
BoxUserOutput, | ||
} from '@filestorage/user/services/box/types'; | ||
import { | ||
BoxSharedLinkInput, | ||
BoxSharedLinkOutput, | ||
} from '@filestorage/sharedlink/services/box/types'; | ||
|
||
/* file */ | ||
export type OriginalFileInput = BoxFileInput | OnedriveFileInput; | ||
export type OriginalFileInput = | ||
| BoxFileInput | ||
| OnedriveFileInput | ||
| SharepointFileInput; | ||
|
||
/* folder */ | ||
export type OriginalFolderInput = BoxFolderInput | OnedriveFolderInput; | ||
export type OriginalFolderInput = | ||
| BoxFolderInput | ||
| OnedriveFolderInput | ||
| SharepointFolderInput; | ||
|
||
/* permission */ | ||
export type OriginalPermissionInput = any | OnedrivePermissionInput; | ||
export type OriginalPermissionInput = | ||
| any | ||
| OnedrivePermissionInput | ||
| SharepointPermissionInput; | ||
|
||
Comment on lines
+120
to
+123
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider removing the The addition of However, the presence of the |
||
/* shared link */ | ||
export type OriginalSharedLinkInput = any; | ||
|
||
/* drive */ | ||
export type OriginalDriveInput = any | OnedriveDriveInput; | ||
export type OriginalDriveInput = | ||
| any | ||
| OnedriveDriveInput | ||
| SharepointDriveInput; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider removing the The addition of However, the presence of the |
||
/* group */ | ||
export type OriginalGroupInput = BoxGroupInput | OnedriveGroupInput; | ||
export type OriginalGroupInput = | ||
| BoxGroupInput | ||
| OnedriveGroupInput | ||
| SharepointGroupInput; | ||
|
||
/* user */ | ||
export type OriginalUserInput = BoxUserInput | OnedriveUserInput; | ||
export type OriginalUserInput = | ||
| BoxUserInput | ||
| OnedriveUserInput | ||
| SharepointUserInput; | ||
|
||
export type FileStorageObjectInput = | ||
| OriginalFileInput | ||
|
@@ -89,25 +142,43 @@ export type FileStorageObjectInput = | |
/* OUTPUT */ | ||
|
||
/* file */ | ||
export type OriginalFileOutput = BoxFileOutput | OnedriveFileOutput; | ||
export type OriginalFileOutput = | ||
| BoxFileOutput | ||
| OnedriveFileOutput | ||
| SharepointFileOutput; | ||
|
||
/* folder */ | ||
export type OriginalFolderOutput = BoxFolderOutput | OnedriveFolderOutput; | ||
export type OriginalFolderOutput = | ||
| BoxFolderOutput | ||
| OnedriveFolderOutput | ||
| SharepointFolderOutput; | ||
|
||
/* permission */ | ||
export type OriginalPermissionOutput = any | OnedrivePermissionOutput; | ||
export type OriginalPermissionOutput = | ||
| any | ||
| OnedrivePermissionOutput | ||
| SharepointPermissionOutput; | ||
|
||
Comment on lines
+169
to
+172
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider removing the The addition of However, the presence of the |
||
/* shared link */ | ||
export type OriginalSharedLinkOutput = any; | ||
|
||
/* drive */ | ||
export type OriginalDriveOutput = any | OnedriveDriveOutput; | ||
export type OriginalDriveOutput = | ||
| any | ||
| OnedriveDriveOutput | ||
| SharepointDriveOutput; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Consider removing the The addition of However, the presence of the |
||
/* group */ | ||
export type OriginalGroupOutput = BoxGroupOutput | OnedriveGroupOutput; | ||
export type OriginalGroupOutput = | ||
| BoxGroupOutput | ||
| OnedriveGroupOutput | ||
| SharepointGroupOutput; | ||
|
||
/* user */ | ||
export type OriginalUserOutput = BoxUserOutput | OnedriveUserOutput; | ||
export type OriginalUserOutput = | ||
| BoxUserOutput | ||
| OnedriveUserOutput | ||
| SharepointUserOutput; | ||
|
||
export type FileStorageObjectOutput = | ||
| OriginalFileOutput | ||
|
@@ -120,8 +191,10 @@ export type FileStorageObjectOutput = | |
|
||
export type OriginalSharedlinkInput = | ||
| BoxSharedLinkInput | ||
| OnedriveSharedLinkInput; | ||
| OnedriveSharedLinkInput | ||
| SharepointSharedLinkInput; | ||
|
||
export type OriginalSharedlinkOutput = | ||
| BoxSharedLinkOutput | ||
| OnedriveSharedLinkOutput; | ||
| OnedriveSharedLinkOutput | ||
| SharepointSharedLinkOutput; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { EncryptionService } from '@@core/@core-services/encryption/encryption.service'; | ||
import { LoggerService } from '@@core/@core-services/logger/logger.service'; | ||
import { PrismaService } from '@@core/@core-services/prisma/prisma.service'; | ||
import { ApiResponse } from '@@core/utils/types'; | ||
import { SyncParam } from '@@core/utils/types/interface'; | ||
import { FileStorageObject } from '@filestorage/@lib/@types'; | ||
import { IDriveService } from '@filestorage/drive/types'; | ||
import { Injectable } from '@nestjs/common'; | ||
import axios from 'axios'; | ||
import { ServiceRegistry } from '../registry.service'; | ||
import { SharepointDriveOutput } from './types'; | ||
import { DesunifyReturnType } from '@@core/utils/types/desunify.input'; | ||
import { OriginalDriveOutput } from '@@core/utils/types/original/original.file-storage'; | ||
|
||
@Injectable() | ||
export class SharepointService implements IDriveService { | ||
constructor( | ||
private prisma: PrismaService, | ||
private logger: LoggerService, | ||
private cryptoService: EncryptionService, | ||
private registry: ServiceRegistry, | ||
) { | ||
this.logger.setContext( | ||
`${FileStorageObject.file.toUpperCase()}:${SharepointService.name}`, | ||
); | ||
this.registry.registerService('sharepoint', this); | ||
} | ||
|
||
async addDrive( | ||
driveData: DesunifyReturnType, | ||
linkedUserId: string, | ||
): Promise<ApiResponse<OriginalDriveOutput>> { | ||
// No API to add drive in Sharepoint | ||
return; | ||
} | ||
Comment on lines
+29
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Clarify the stub for The |
||
|
||
async sync(data: SyncParam): Promise<ApiResponse<SharepointDriveOutput[]>> { | ||
try { | ||
const { linkedUserId } = data; | ||
|
||
const connection = await this.prisma.connections.findFirst({ | ||
where: { | ||
id_linked_user: linkedUserId, | ||
provider_slug: 'sharepoint', | ||
vertical: 'filestorage', | ||
}, | ||
}); | ||
|
||
const resp = await axios.get(`${connection.account_url}/drives`, { | ||
headers: { | ||
'Content-Type': 'application/json', | ||
Authorization: `Bearer ${this.cryptoService.decrypt( | ||
connection.access_token, | ||
)}`, | ||
}, | ||
}); | ||
|
||
const drives: SharepointDriveOutput[] = resp.data.value; | ||
this.logger.log(`Synced sharepoint drives !`); | ||
|
||
return { | ||
data: drives, | ||
message: 'Sharepoint drives retrived', | ||
statusCode: 200, | ||
}; | ||
} catch (error) { | ||
console.log(error.response); | ||
throw error; | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
import { MappersRegistry } from '@@core/@core-services/registries/mappers.registry'; | ||
import { CoreUnification } from '@@core/@core-services/unification/core-unification.service'; | ||
import { Utils } from '@filestorage/@lib/@utils'; | ||
import { | ||
UnifiedFilestorageDriveInput, | ||
UnifiedFilestorageDriveOutput, | ||
} from '@filestorage/drive/types/model.unified'; | ||
import { Injectable } from '@nestjs/common'; | ||
import { SharepointDriveInput, SharepointDriveOutput } from './types'; | ||
import { IDriveMapper } from '@filestorage/drive/types'; | ||
|
||
@Injectable() | ||
export class SharepointDriveMapper implements IDriveMapper { | ||
constructor( | ||
private mappersRegistry: MappersRegistry, | ||
private utils: Utils, | ||
private coreUnificationService: CoreUnification, | ||
) { | ||
this.mappersRegistry.registerService( | ||
'filestorage', | ||
'drive', | ||
'sharepoint', | ||
this, | ||
); | ||
} | ||
|
||
async desunify( | ||
source: UnifiedFilestorageDriveInput, | ||
customFieldMappings?: { | ||
slug: string; | ||
remote_id: string; | ||
}[], | ||
): Promise<SharepointDriveInput> { | ||
return; | ||
Comment on lines
+27
to
+34
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Incomplete implementation of The Would you like me to help draft the implementation or should this be tracked as a task in your project management tool? |
||
} | ||
|
||
async unify( | ||
source: SharepointDriveOutput | SharepointDriveOutput[], | ||
connectionId: string, | ||
customFieldMappings?: { | ||
slug: string; | ||
remote_id: string; | ||
}[], | ||
): Promise<UnifiedFilestorageDriveOutput | UnifiedFilestorageDriveOutput[]> { | ||
if (!Array.isArray(source)) { | ||
return await this.mapSingleDriveToUnified( | ||
source, | ||
connectionId, | ||
customFieldMappings, | ||
); | ||
} | ||
// Handling array of SharepointDriveOutput | ||
return Promise.all( | ||
source.map((drive) => | ||
this.mapSingleDriveToUnified(drive, connectionId, customFieldMappings), | ||
), | ||
); | ||
} | ||
|
||
private async mapSingleDriveToUnified( | ||
drive: SharepointDriveOutput, | ||
connectionId: string, | ||
customFieldMappings?: { | ||
slug: string; | ||
remote_id: string; | ||
}[], | ||
): Promise<UnifiedFilestorageDriveOutput> { | ||
const field_mappings: { [key: string]: any } = {}; | ||
if (customFieldMappings) { | ||
for (const mapping of customFieldMappings) { | ||
field_mappings[mapping.slug] = drive[mapping.remote_id]; | ||
} | ||
} | ||
|
||
const result: UnifiedFilestorageDriveOutput = { | ||
remote_id: drive.id, | ||
remote_data: drive, | ||
name: drive.name, | ||
remote_created_at: drive.createdDateTime, | ||
drive_url: drive.webUrl, | ||
field_mappings, | ||
}; | ||
|
||
return result; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approve the changes with a suggestion to add error handling.
The code changes introduce a new mechanism to dynamically fetch the
site_id
using the Microsoft Graph API, which is an improvement over using thesite
parameter directly. This change aligns with the best practices for accessing SharePoint resources by using the correct identifiers in API calls.The
axios
library is being used to make the API call and theaccess_token
from the OAuth response is being used for authentication, which looks good.Consider adding error handling for the API call to gracefully handle any errors that may occur during the request. You can use a
try-catch
block to catch any errors and log them using thelogger
service.