Skip to content
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

Release/2.4.4 #111

Open
wants to merge 30 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
dd6eea7
Moved getErrorDescription(error:) to an Error extension for better co…
patricioxavier8 Oct 18, 2024
cecc565
Refactor code to migrate to new endpoint service.
patricioxavier8 Oct 30, 2024
469c336
replace createfiledata struct to new version
patricioxavier8 Oct 30, 2024
31b8960
Merge pull request #106 from internxt/feature/migrate-new-api
patricioxavier8 Nov 5, 2024
84d7a82
refactor movefileuse case to use new api
patricioxavier8 Nov 6, 2024
2e4a904
Merge pull request #107 from internxt/feature/migrate-new-api
patricioxavier8 Nov 6, 2024
84ba08c
Add new functions to create new virtual drive.
patricioxavier8 Nov 9, 2024
68d2135
-fix rename folder in workspace
patricioxavier8 Nov 10, 2024
b9b7cac
add operations to trahs folders in workspace
patricioxavier8 Nov 10, 2024
018da95
add download files in workspace
patricioxavier8 Nov 10, 2024
7ba8de4
add trash file in workspace
patricioxavier8 Nov 11, 2024
964475b
add move file in workspace
patricioxavier8 Nov 11, 2024
d8124eb
update project
patricioxavier8 Nov 11, 2024
2e3176a
add move folder for workspace
patricioxavier8 Nov 11, 2024
8cfae0d
migrate move folder to use new api
patricioxavier8 Nov 11, 2024
0598c24
add networkAuth to manage workspace
patricioxavier8 Nov 28, 2024
1b05a87
update functions to upload or udapte files in workspace
patricioxavier8 Nov 28, 2024
3778aff
add better error description in update file workspace
patricioxavier8 Nov 28, 2024
1b13cb2
fix minor error in rename file workspace
patricioxavier8 Nov 28, 2024
259ff7e
fix error when user load many folders in workspace
patricioxavier8 Nov 28, 2024
dd1252b
add new param in activyentry class
patricioxavier8 Nov 28, 2024
d952667
add id to save activity entry when user download a file
patricioxavier8 Nov 28, 2024
f47a36d
-fix error when user download a file
patricioxavier8 Nov 28, 2024
e66e493
add new file to show logs from workspaces
patricioxavier8 Dec 2, 2024
1b15d99
add mainActor to avoid async when use realm in backup
patricioxavier8 Dec 2, 2024
3a6ec2f
add get remote changes for workspace
patricioxavier8 Dec 2, 2024
9ec1627
add remote changes in enumerator
patricioxavier8 Dec 2, 2024
b3c9a6e
update version
patricioxavier8 Dec 3, 2024
c8d8f09
fix getRemoteChanges, increase offset.
patricioxavier8 Dec 4, 2024
d59dfa6
minor fixes
patricioxavier8 Dec 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 83 additions & 7 deletions InternxtDesktop.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion InternxtDesktop/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -296,10 +296,18 @@ class AppDelegate: NSObject, NSApplicationDelegate , PKPushRegistryDelegate {
guard let user = self.authManager.user else {
throw AuthError.noUserFound
}

try await domainManager.initFileProviderForUser(user:user)


self.logger.info("Login success")

guard let workspaces = self.authManager.availableWorkspaces else {
return
}
try await domainManager.initFileProviderForUserWorkspace(user: user, workspaces: workspaces)

self.logger.info("Workspaces setted correctly")
} catch {
self.logger.error("Failed to start the app: \(error)" )
error.reportToSentry()
Expand Down
19 changes: 18 additions & 1 deletion InternxtDesktop/Services/Auth/AuthManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,17 @@ class AuthManager: ObservableObject {
let logger = Logger(subsystem: "com.internxt", category: "AuthManager")
@Published public var isLoggedIn = false
@Published public var user: DriveUser? = nil
@Published public var availableWorkspaces: [AvailableWorkspace]? = []
@Published public var workspaceCredentials: WorkspaceCredentialsResponse? = nil

public let config = ConfigLoader()
public let cryptoUtils = CryptoUtils()
private let REFRESH_TOKEN_DEADLINE = 5
init() {
self.isLoggedIn = checkIsLoggedIn()
self.user = config.getUser()
self.availableWorkspaces = config.getWorkspaces()
self.workspaceCredentials = config.getWorkspaceCredentials()
}

public var mnemonic: String? {
Expand Down Expand Up @@ -59,10 +64,20 @@ class AuthManager: ObservableObject {
uuid: refreshUserResponse.user.uuid
)
try config.setUser(user: refreshUserResponse.user)

let workspaces = try await APIFactory.DriveNew.getAvailableWorkspaces(debug: true)
try config.setAvailableWorkspaces(workspaces: workspaces.availableWorkspaces)
if !workspaces.availableWorkspaces.isEmpty{
let credentials = try await APIFactory.DriveNew.getCredentialsWorkspaces(workspaceId: workspaces.availableWorkspaces[0].workspaceUser.workspaceId, debug: true)
try config.setWorkspaceCredentials(credentials: credentials)
DispatchQueue.main.async{ self.workspaceCredentials = credentials}
}
DispatchQueue.main.async{
self.user = refreshUserResponse.user
self.availableWorkspaces = workspaces.availableWorkspaces
}



}

func refreshTokens() async throws {
Expand Down Expand Up @@ -92,6 +107,8 @@ class AuthManager: ObservableObject {
try config.removeAuthToken()
try config.removeLegacyAuthToken()
try config.removeMnemonic()
try config.removeWorkspaces()
try config.removeWorkspaceCredentials()
user = nil
ErrorUtils.clean()
isLoggedIn = false
Expand Down
18 changes: 18 additions & 0 deletions InternxtDesktop/Services/FileProviderDomainManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ class FileProviderDomainManager: ObservableObject {
}
self.manager = nil
self.managerDomain = nil
try? await NSFileProviderManager.removeAllDomains()
}


Expand All @@ -67,4 +68,21 @@ class FileProviderDomainManager: ObservableObject {
self.domainStatus = newStatus
}
}

public func initFileProviderForUserWorkspace(user: DriveUser, workspaces: [AvailableWorkspace]) async throws {
do {
if !workspaces.isEmpty{
let identifier = NSFileProviderDomainIdentifier(rawValue: workspaces[0].workspaceUser.workspaceId)
let domain = NSFileProviderDomain(identifier: identifier, displayName: "Internxt Business")

try await NSFileProviderManager.add(domain)

self.logger.info("📦 FileProvider domain workspace is ready with identifier \(identifier.rawValue)")
}

return
} catch {
throw error
}
}
}
9 changes: 9 additions & 0 deletions Shared/Extensions/Error.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,21 @@

import Foundation
import Sentry
import InternxtSwiftCore

extension Error {
func reportToSentry() {
sentryLogger.error("\(String(describing: self))")
SentrySDK.capture(error: self)
}

func getErrorDescription() -> String {
if let apiClientError = self as? APIClientError {
let responseBody = String(decoding: apiClientError.responseBody, as: UTF8.self)
return "APIClientError \(apiClientError.statusCode) - \(responseBody)"
}
return self.localizedDescription
}
}

extension NSAlert {
Expand Down
2 changes: 2 additions & 0 deletions Shared/Services/ActivityManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -110,11 +110,13 @@ class ActivityEntry: Object {
@Persisted var status: ActivityEntryStatus

convenience init(
_id: ObjectId? = nil,
filename: String,
kind: ActivityEntryOperationKind,
status: ActivityEntryStatus
) {
self.init()
self._id = _id ?? ObjectId.generate()
self.filename = filename
self.createdAt = Date()
self.kind = kind
Expand Down
91 changes: 91 additions & 0 deletions Shared/Services/ConfigLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ enum ConfigLoaderError: Error {
case CannotRemoveUser
case CannotSaveOnboardingIsCompleted
case CannotHideBackupBanner
case CannotSaveWorkspaces
case CannotSaveWorkspacesCredentials
}


Expand Down Expand Up @@ -121,6 +123,24 @@ public struct ConfigLoader {
return userAndPass.data(using: .utf8)?.base64EncodedString()
}


public func getNetworkAuthWorkspace() -> String? {

guard let credentials = getWorkspaceCredentials() else {
return nil
}
var hasher = SHA256()

hasher.update(data: credentials.credentials.networkPass.data(using: .utf8)!)

let digest = hasher.finalize()
var result = [UInt8]()
digest.withUnsafeBytes {bytes in
result.append(contentsOf: bytes)
}
let userAndPass = "\(credentials.credentials.networkUser):\(CryptoUtils().bytesToHexString(result))"
return userAndPass.data(using: .utf8)?.base64EncodedString()
}
public func getUser() -> DriveUser? {
let userStr = self.getFromUserDefaults(key: "DriveUser")
guard let userData = userStr?.data(using: .utf8) else {
Expand Down Expand Up @@ -273,6 +293,77 @@ public struct ConfigLoader {
public func getDeviceName() -> String? {
return Host.current().localizedName
}

public func setAvailableWorkspaces(workspaces: [AvailableWorkspace]) throws -> Void {
let jsonData = try JSONEncoder().encode(workspaces)
guard let jsonString = String(data: jsonData, encoding: .utf8) else {
throw ConfigLoaderError.CannotSaveWorkspaces
}

let saved = self.saveToUserDefaults(key: "AvailableWorkspaces", value: jsonString)

if saved == false {
throw ConfigLoaderError.CannotSaveWorkspaces
}
}

public func getWorkspaces() -> [AvailableWorkspace]? {
let workspaces = self.getFromUserDefaults(key: "AvailableWorkspaces")
guard let workspacesData = workspaces?.data(using: .utf8) else {
return nil
}
do {
let jsonData = try JSONDecoder().decode([AvailableWorkspace].self, from: workspacesData)
return jsonData
} catch {
print(error)
return nil
}
}

public func removeWorkspaces() throws -> Void {
let removed = self.removeFromUserDefaults(key: "AvailableWorkspaces")

if removed == false {
throw ConfigLoaderError.CannotRemoveKey
}
}

public func setWorkspaceCredentials(credentials: WorkspaceCredentialsResponse) throws -> Void {
let jsonData = try JSONEncoder().encode(credentials)
guard let jsonString = String(data: jsonData, encoding: .utf8) else {
throw ConfigLoaderError.CannotSaveWorkspacesCredentials
}

let saved = self.saveToUserDefaults(key: "WorkspaceCredentials", value: jsonString)

if saved == false {
throw ConfigLoaderError.CannotSaveWorkspacesCredentials
}
}

public func getWorkspaceCredentials() -> WorkspaceCredentialsResponse? {
let workspaces = self.getFromUserDefaults(key: "WorkspaceCredentials")
guard let workspacesData = workspaces?.data(using: .utf8) else {
return nil
}
do {
let jsonData = try JSONDecoder().decode(WorkspaceCredentialsResponse.self, from: workspacesData)
return jsonData
} catch {
print(error)
return nil
}
}

public func removeWorkspaceCredentials() throws -> Void {
let removed = self.removeFromUserDefaults(key: "WorkspaceCredentials")

if removed == false {
throw ConfigLoaderError.CannotRemoveKey
}
}

}


8 changes: 4 additions & 4 deletions Shared/Services/DriveFileService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,19 @@ struct DriveFileService {
public func renameFile(uuid: String, bucketId: String, newName: String) async throws -> DriveFile {
let fileMeta = try await driveNewAPI.getFileMetaByUuid(uuid: uuid)

let updated = try await driveAPI.updateFile(
fileId: fileMeta.fileId,
let updated = try await driveNewAPI.updateFileNew(
uuid: fileMeta.uuid,
bucketId: bucketId,
newFilename: newName,
debug: false
debug: true
)

let createdAt = Time.dateFromISOString(fileMeta.createdAt) ?? Date()
let updatedAt = Time.dateFromISOString(fileMeta.updatedAt) ?? Date()

return DriveFile(
uuid: fileMeta.uuid,
plainName: updated.plain_name,
plainName: updated.plainName,
name: fileMeta.name,
type: fileMeta.type,
size: Int(fileMeta.size) ?? 0,
Expand Down
2 changes: 2 additions & 0 deletions Shared/Services/LogService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ enum LogSubSystem: String {
case InternxtDesktop = "com.internxt.InternxtDesktop"
case XPCBackups = "com.internxt.XPCBackups"
case Errors = "com.internxt.errors"
case SyncExtensionWorkspace = "com.internxt.SyncExtension.Workspace"
}

struct LogService {
Expand Down Expand Up @@ -95,3 +96,4 @@ struct LogService {

let syncExtensionLogger = LogService.shared.createLogger(subsystem: .SyncExtension, category: "SyncExtension")
let appLogger = LogService.shared.createLogger(subsystem: .InternxtDesktop, category: "InternxtDesktopUIApp")
let syncExtensionWorkspaceLogger = LogService.shared.createLogger(subsystem: .SyncExtensionWorkspace, category: "SyncExtensionWorkspace")
27 changes: 27 additions & 0 deletions Shared/Utils/APIFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ struct APIFactory {
return NetworkAPI(baseUrl: config.NETWORK_API_URL, basicAuthToken: networkAuth!, clientName: CLIENT_NAME, clientVersion: getVersion())
}

static var NetworkWorkspace: NetworkAPI {
let configLoader = ConfigLoader()

let config = configLoader.get()
let networkAuth = configLoader.getNetworkAuthWorkspace()
return NetworkAPI(baseUrl: config.NETWORK_API_URL, basicAuthToken: networkAuth!, clientName: CLIENT_NAME, clientVersion: getVersion())
}

static var DriveNew: DriveAPI {
let configLoader = ConfigLoader()

Expand All @@ -46,6 +54,15 @@ struct APIFactory {
return DriveAPI(baseUrl: config.DRIVE_NEW_API_URL, authToken: token, clientName: CLIENT_NAME, clientVersion: getVersion())
}

static var DriveWorkspace: DriveAPI {
let configLoader = ConfigLoader()

let config = configLoader.get()
let token = configLoader.getAuthToken() ?? "MISSING_TOKEN"
let workspaceHeader = configLoader.getWorkspaceCredentials()?.tokenHeader
return DriveAPI(baseUrl: config.DRIVE_NEW_API_URL, authToken: token, clientName: CLIENT_NAME, clientVersion: getVersion(),workspaceHeader: workspaceHeader)
}

static var Drive: DriveAPI {
let configLoader = ConfigLoader()

Expand All @@ -72,6 +89,16 @@ struct APIFactory {

return TrashAPI(baseUrl: config.DRIVE_NEW_API_URL, authToken: token, clientName: CLIENT_NAME, clientVersion: getVersion())
}

static var TrashWorkspace: TrashAPI {
let configLoader = ConfigLoader()

let config = configLoader.get()
let token = configLoader.getAuthToken() ?? "MISSING_TOKEN"
let workspaceHeader = configLoader.getWorkspaceCredentials()?.tokenHeader

return TrashAPI(baseUrl: config.DRIVE_NEW_API_URL, authToken: token, clientName: CLIENT_NAME, clientVersion: getVersion(),workspaceHeader: workspaceHeader)
}

static var Backup: BackupAPI {
let configLoader = ConfigLoader()
Expand Down
16 changes: 13 additions & 3 deletions SyncExtension/FileProviderEnumerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
private let anchor = NSFileProviderSyncAnchor(initialAnchor.data(using: .utf8)!)
private let driveAPI = APIFactory.Drive
private let user: DriveUser
init(user: DriveUser, enumeratedItemIdentifier: NSFileProviderItemIdentifier) {
private let domain: NSFileProviderDomain
private let workspace: [AvailableWorkspace]
init(user: DriveUser, enumeratedItemIdentifier: NSFileProviderItemIdentifier , domain: NSFileProviderDomain, workspace: [AvailableWorkspace]) {
self.enumeratedItemIdentifier = enumeratedItemIdentifier
self.user = user
self.domain = domain
self.workspace = workspace
super.init()
}

Expand Down Expand Up @@ -51,14 +55,20 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {


let suggestedPageSize: Int = observer.suggestedPageSize ?? 50
let isPersonalDrive = domain.identifier.rawValue == user.uuid

return isPersonalDrive ? EnumerateFolderItemsUseCase(user:self.user,enumeratedItemIdentifier: self.enumeratedItemIdentifier, for: observer, from: page).run(limit: suggestedPageSize > 50 ? 50 :suggestedPageSize) :
EnumerateFolderItemsWorkspaceUseCase(user:self.user,enumeratedItemIdentifier: self.enumeratedItemIdentifier, for: observer, from: page, workspace: workspace).run(limit: suggestedPageSize > 50 ? 50 :suggestedPageSize)

return EnumerateFolderItemsUseCase(user:self.user,enumeratedItemIdentifier: self.enumeratedItemIdentifier, for: observer, from: page).run(limit: suggestedPageSize > 50 ? 50 :suggestedPageSize)
}


func enumerateChanges(for observer: NSFileProviderChangeObserver, from anchor: NSFileProviderSyncAnchor) {
let isPersonalDrive = domain.identifier.rawValue == user.uuid

return GetRemoteChangesUseCase(observer: observer, anchor: anchor,user: user).run()
return isPersonalDrive ? GetRemoteChangesUseCase(observer: observer, anchor: anchor,user: user).run() :
GetRemoteChangesUseCaseWorkspace(observer: observer, anchor: anchor,workspace: workspace).run()

}

func currentSyncAnchor(completionHandler: @escaping (NSFileProviderSyncAnchor?) -> Void) {
Expand Down
Loading
Loading