PrivMX DOCS
Swift

Working with Inboxes

Inboxes are a secure way for assigned members to receive encrypted inbound traffic from public sources.

Inboxes provide a secure way to receive entries from both internal and external sources.

  • Entries can contain binary data and files.
  • Each Context can contain any number of Inboxes with unique identifiers (inboxId) used to distinguish them.
  • Everyone with access to inboxID, solutionID, and Bridge URL can send an entry, but only the users who are added to given Inbox can read them.

Permissions

The user list in Inbox is designed to be flexible, accommodating a wide range of use cases.

Inboxes differentiate three types of users: Regular Users, Managers, and External Users. The table below shows what actions can be performed by each type of users:

ActivityUserManagerExternal
Submitting entriesyesyesyes
Listing entriesyesyesno
Deleting entriesnoyesno
Editing Inboxnoyesno

The values above are the default policy values defined by PrivMX. To read more about Policies and learn how to modify them, go to Policies.

Sample code on this page is based on the initial assumptions.

publicMeta and privateMeta fields in Inboxes support any kind of data formats encoded to byte arrays. Examples in this section use JSON format serialization, which is available directly in Swift.

Working with Inboxes

To access Inbox methods, get the field inboxApi from active connection. Connection should be initialized with [.inbox] and passed to PrivmxEndpoint.

Swift
guard let endpointSession =
        try? await endpointContainer?.newEndpoint(
            enabling: [.inbox],
            connectingAs: USER1_PRIVATE_KEY,
            to: SOLUTION_ID,
            on: BRIDGE_URL ) else {return}
endpointSession.inboxApi // instance of InboxApi

Public session

Public submissions require using newPublicEndpoint function, provided by the EndpointContainer class, to establish a public connection to the Platform. After connecting, create an InboxApi instance, which allows to operate on Inboxes.

Swift
guard let publicEndpointSession =
        try? await endpointContainer?.newPublicEndpoint(
            enabling: [.inbox],
            to: SOLUTION_ID,
            on: BRIDGE_URL ) else {return}
publicEndpointSession.inboxApi // instance of Public InboxApi

Alternatively You can init publicInboxApi by:

Swift
guard var publicConnection =
        try? Connection.connectPublic(
            to: SOLUTION_ID,
            on: BRIDGE_URL) as? Connection
        
else {return}

guard var publicStoreApi =
        try? StoreApi.create(
            connection: &publicConnection) else {return}
guard var publicThreadApi =
        try? ThreadApi.create(
            connection: &publicConnection) else {return}
guard let publicInboxApi =
        try? InboxApi.create(
            connection: &publicConnection,
            threadApi: &publicThreadApi,
            storeApi: &publicStoreApi) else {return}

Assumptions

We use some structures in following examples:

Swift
struct InboxPublicMeta:Codable{
    let tags: [String]
    //definition by developer
}

Creating Inboxes

To create an Inbox, you need to name it and provide a list of public key - userID pairs. Due to the fact that each Inbox is inside a Context, all the public keys have to be registered inside the given Context. You can do it using Bridge API context/addUserToContext method.

While creating an Inbox, you can also provide additional information:

  • publicMeta contains additional info about the Inbox. It is not encrypted before sending to PrivMX Bridge. Inbox API provides methods for accessing this field as publicView. For more information about Inbox publicView and its common use cases go to Using Public View.

  • privateMeta this field will be encrypted by PrivMX Endpoint before sending to PrivMX Bridge. It's meant to store additional sensitive information about the Inbox. privateMeta is accessible only for users registered to the given Inbox.

  • filesConfig you can specify up front file requirements for each entry submitted to the Inbox. This config includes min and max count of files in an entry, their max size, but also max size of whole upload.

  • policy determines what actions will be available to specific users. For more information and use cases, go to Policies.

Creating a basic, unnamed Inbox, which can act as an encrypted data container:

Swift
 let users = [privmx.endpoint.core.UserWithPubKey]() //should be prepared by developer
let managers = [privmx.endpoint.core.UserWithPubKey]() //should be prepared by developer
let publicMeta = Data()
let privateMeta = Data()

let inboxId = try? endpointSession?.inboxApi?.createInbox(
    in: contextId,
    for: users,
    managedBy: managers,
    withPublicMeta: publicMeta,
    withPrivateMeta: privateMeta,
    withFilesConfig: nil,
    withPolicies: nil
    )

Listing Inboxes

Your application may include multiple Inboxes, each associated with different Contexts. You can retrieve a list of all Inboxes within a given Context. This list, alongside the metadata you sent while creating the Inbox, will include useful metadata about the Inbox, such as the creation date, last file upload date, user list, and information about the last modification.

PrivMX Endpoint takes care of decrypting received data, which means you only have to take care of decoding them from binary format.

Fetching the most recent Inboxes in given Context:

Swift
let startIndex:Int64 = 0
let pageSize:Int64 = 100

guard let pagingList = try? endpointSession?.inboxApi?
    .listInboxes(
        from:contextId,
        basedOn: .init(skip: startIndex, limit: pageSize, sortOrder: .desc)) else {return}

let inboxes = pagingList.readItems.map { $0 }

Using Public View

Users with public connection have access to the Public View which shares not encrypted fields of the Inbox, such as publicMeta.

Swift
    let inboxID = "INBOX_ID" 
    guard let inboxPublicView = try? publicEndpointSession?.inboxApi?.getInboxPublicView(for: inboxID) else {return}
    guard let inboxPublicMetaData = inboxPublicView.publicMeta.getData() else {return}
    let inboxPublicMetaDecoded = try? JSONDecoder().decode(InboxPublicMeta.self, from: inboxPublicMetaData)

Modifying Inboxes

Depending on your project's specification, it may be necessary to modify an Inbox. It could be, for example, changing the name or adding/removing users. Each user with management rights is able to modify Inboxes, delete them as a whole or only particular entries.

Three additional options are available when changing the list of users inside an Inbox:

  • force - applies an update, without checking the current version.
  • forceGenerateNewKey - re-encrypts entries in the Inbox. It's useful when a user is removed, and you want to prevent them from accessing the Inbox.
  • policy - you can also pass a new policy object as the last optional argument.

Updating an Inbox means overwriting it with the provided data. To successfully update an Inbox, you must specify its current version. The version field is mandatory to handle multiple updates on the server, and it is incremented by 1 with each update.

To update an Inbox you must always provide its current version, as well as:

  • list of users
  • list of managers
  • new private and public meta (even if it didn't change)
  • Inbox's current version
  • Inbox FilesConfig
  • true if update action should be forced
Swift
let inboxId = "INBOX_ID"
        let inboxPublicMeta = InboxPublicMeta(tags: ["TAG1","TAG2","TAG3"])
        guard let publicMeta = try? JSONEncoder().encode(inboxPublicMeta) else {return}
        guard let inbox = try? endpointSession?.inboxApi?
            .getInbox(inboxId) else {return}

        //users list to be extracted from inbox
        let users = inbox.users.map{
            //Your application must provide a way,
            //to get user's public key from their userId.
            privmx.endpoint.core.UserWithPubKey(userId: $0, pubKey: "PUB")
        }
        //managers list to be extracted from inbox
        let managers = inbox.managers.map{
            //Your application must provide a way,
            //to get user's public key from their userId.
            privmx.endpoint.core.UserWithPubKey(userId: $0, pubKey: "PUB")
        }

        guard let newPrivateMeta = "New Inbox name".data(using: .utf8) else {return}
        guard let filesConfig:privmx.endpoint.inbox.FilesConfig = inbox.filesConfig.value else {return}

        _ = try? endpointSession?.inboxApi?.updateInbox(
            inboxId,
            replacingUsers: users,
            replacingManagers: managers,
            replacingPublicMeta: inbox.publicMeta.getData() ?? Data(),
            replacingPrivateMeta: newPrivateMeta,
            replacingFilesConfig: filesConfig,
            atVersion: inbox.version,
            force:false,
            forceGenerateNewKey: false,
            replacingPolicies:nil)

We use cookies on our website. We use them to ensure proper functioning of the site and, if you agree, for purposes such as analytics, marketing, and targeting ads.

PrivMX Endpoint Swift v2.6

This package is not up to date with the core documentation. Some of the features you've seen described in other parts of the documentation might not be mentioned here. Those changes do not influence compatibility, however

On this page

Working with Inboxes | PrivMX Docs