Right after the initialization of the Tanker class, its internal status is STOPPED. Operations like encryption or sharing are not possible. To allow them, you first need to start a session.

Starting a session

To start a session, you will need to use the user's Tanker identity, and call the start method. This method returns a status, which tells you what to do next:

  • The READY status means that the Tanker session is started and ready to be used.
  • The IDENTITY_REGISTRATION_NEEDED status means that Tanker does not know this user yet. Their identity must be registered with the Tanker service, along with a method to verify it.
  • The IDENTITY_VERIFICATION_NEEDED status means that Tanker needs to verify the user's identity. It happens for instance when the user starts a Tanker session on a new device.

Once the identity is registered or verified, the internal Tanker status changes to ready, and the session is ready to be used.

Identity verification methods

To register and later verify identities, you will need to use one of the following verification methods:

Here is how it looks like:

public void startTanker() {
  // Authenticate the user with your server
  User user = authenticateUser();

  // Start a Tanker session for the user
  Status status = tanker.start(user.tankerIdentity);

  switch (status) {
    case Status.IDENTITY_REGISTRATION_NEEDED:
      // Ask the application server to send a verification code via Tanker
      app.sendVerificationCode(emailAddress);

      // Wait for the user to input the verification code
      String verificationCode = app.promptUser("Enter your verification code:");

      // Register the identity
      tanker.registerIdentity(new EmailVerification(emailAddress, verificationCode)).get();
      break;
    case Status.IDENTITY_VERIFICATION_NEEDED:
      // Ask the application server to send a verification code via Tanker
      app.sendVerificationCode(emailAddress);

      // Wait for the user to input the verification code
      String verificationCode = app.promptUser("Enter your verification code:");

      // Verify the identity
      tanker.verifyIdentity(new EmailVerification(emailAddress, verificationCode)).get();
      break;
    case Status.READY:
      // Well... you're ready :)
      break;
    default:
      throw new RuntimeException("Unknown status " + status);
  }
}

NSString* email = @"user@example.com";

- (void)startTanker(TKRStartHandler startHandler)
{
  // Authenticate the user with your server
  User* user = [self.app authenticateUser];

  // Start a Tanker session for the user
  [self.tanker startWithIdentity:user.identity completionHandler:startHandler];
}


TKRStartHandler startHandler = ^(TKRStatus status, NSError* err) {
  if (err == nil) {
    if (status == TKRStatusIdentityRegistrationNeeded)
    {
      // Ask the application server to send a verification code via Tanker
      [self.app sendVerificationCode:email];
      // Wait for the user to input the verification code
      NSString* verificationCode = [self.app promptUser:@"Enter your verification code"];
      // Convert the email and verificationCode into a TKRVerification.
      TKRVerification* verification = [TKRVerification verificationFromEmail:email code:verificationCode];

      [self.tanker registerIdentityWithVerification:verification completionHandler:^(NSError* err) {
        if (err == nil) {
          // do something
        }
      })];
    }
    else if (status == TKRStatusIdentityRegistrationNeeded)
    {
      // Ask the application server to send a verification code via Tanker
      [self.app sendVerificationCode:email];
      // Wait for the user to input the verification code
      NSString* verificationCode = [self.app promptUser:@"Enter your verification code"];
      // Convert the email and verificationCode into a TKRVerification.
      TKRVerification* verification = [TKRVerification verificationFromEmail:email code:verificationCode];

      [self.tanker verifyIdentityWithVerification:verification completionHandler:^(NSError* err) {
        if (err == nil) {
          // do something
        }
      }];
    }
    else if (status == TKRStatusReady)
    {
      // Tanker is ready
    }
  }
};

import { Tanker } from '@tanker/client-browser';

const { READY, IDENTITY_REGISTRATION_NEEDED, IDENTITY_VERIFICATION_NEEDED } = Tanker.statuses

const id = 'user-id';
const email = 'user@example.com';

const startTanker = async () => {
  // Authenticate the user with your server
  const user = await app.authenticateUser();

  // Start a Tanker session for the user
  const status = await tanker.start(user.tankerIdentity);

  switch (status) {
    case IDENTITY_REGISTRATION_NEEDED:
      // Ask the application server to send a verification code via Tanker
      await app.sendVerificationCode(email);

      // Wait for the user to input the verification code
      const verificationCode = await app.promptUser('Enter your verification code:');

      // Register the identity
      await tanker.registerIdentity({ email, verificationCode });
      break;
    case IDENTITY_VERIFICATION_NEEDED:
      // Ask the application server to send a verification code via Tanker
      await app.sendVerificationCode(email);

      // Wait for the user to input the verification code
      const verificationCode = await app.promptUser('Enter your verification code:');

      // Verify the identity
      await tanker.verifyIdentity({ email, verificationCode });
      break;
    case READY:
      // Well... you're ready :)
      break;
    default:
      throw new Error(`Assertion error: unknown status ${tanker.status}`);
  }
}

Attaching provisional identities to a user's account

After a user has registered their permanent identity with Tanker, their can attach provisional identities to their Tanker account. Once attached to an account, a provisional identity cannot be attached to any other one.

Doing so will automatically allow the user to decrypt any data shared with the provisional identity. They will also automatically become members of any group the provisional identity was added to and will be able to decrypt any data shared with these groups.

For more information on this topic, you can consult this guide.

To attach a provisional identity to a started Tanker session, call the attachProvisionalIdentity() method. The method will return a result containing:

  • a status, which can be READY if everything worked, or IDENTITY_VERIFICATION_NEEDED if the user needs to provide a verification code to verify the email address.
  • the email address corresponding to the provisional identity

To verify the provisional identity, call verifyProvisionalIdentity().

public void startTanker() {
  // Authenticate the user with your server
  User user = authenticateUser();

  // Start a Tanker session for the user
  Status status = tanker.start(user.tankerIdentity);
  // ...

  // Attach provisional identity
  if (user.provisionalIdentity != null) {
    AttachResult attachResult = tanker.attachProvisionalIdentity(user.provisionalIdentity).get();
    if (attachResult.getStatus() == Status.IDENTITY_VERIFICATION_NEEDED) {
      String emailAddress = ((EmailVerification)attachResult.getVerificationMethod()).getEmail();

      // Ask the application server to send a verification code via Tanker
      app.sendVerificationCode(emailAddress);

      // Wait for the user to input the verification code
      String verificationCode = app.promptUser("Enter your verification code:");

      // Verify the provisional identity
      tanker.verifyProvisionalIdentity(new EmailVerification(emailAddress, verificationCode)).get();
    }
  }
}

// Authenticate the user with your server
NSUser* user = [self.app authenticateUser];

// Start the session
// ...

TKRAttachResultHandler attachResultHandler = ^(TKRAttachResult* result, NSError* err) {
  if (err == nil) {
    if (result.status == TKRStatusVerificationNeeded) {

      // Ask the application server to send a verification code via Tanker
      [self.app sendVerificationCode:result.method.email];
      // Wait for the user to input the verification code
      NSString* verificationCode = [self.app promptUser:@"Enter your verification code:"];
      // Convert the email and verificationCode into a TKRVerification.
      TKRVerification* verification = [TKRVerification verificationFromEmail:result.method.email
                                                                        code:verificationCode];

      [self.tanker verifyProvisionalIdentityWithVerification:verification
                                           completionHandler:^(NSError* err) {
                                             if (err == nil) {
                                               // do something
                                             }
                                           }];
    }
  }
}

[self.tanker attachProvisionalIdentity:user.provisionalIdentity
                     completionHandler:attachResultHandler];

const startTanker = async () => {
  // Authenticate the user with your server
  const user = await app.authenticateUser();

  // Start a Tanker session for the user
  const status = await tanker.start(user.tankerIdentity);
  // ...

  // Attach provisional identity
  if (user.provisionalIdentity) {
    const {
      status,
      verificationMethod
    } = await tanker.attachProvisionalIdentity(user.provisionalIdentity);

    if (status === tanker.statuses.IDENTITY_VERIFICATION_NEEDED) {
      const { email } = verificationMethod;

      // Ask the application server to send a verification code via Tanker
      await app.sendVerificationCode(email);

      // Wait for the user to input the verification code
      const verificationCode = await app.promptUser('Enter your verification code:');

      // Verify the provisional identity
      await tanker.verifyProvisionalIdentity({ email, verificationCode });
    }
  }
}

Stopping the session

At some point you might want to stop() your Tanker session. This changes the internal status back to STOPPED:

private void logout() {
  // Get the Tanker instance from application or other activity
  mTanker.stop().then((closeFuture) -> {
    // Do something when Tanker is stopped (for example redirect to the home page).
    return null;
  });
}

[self.tanker stopWithCompletionHandler:^(NSError* error) {
                    if (error == nil) {
                      // do something when Tanker is stopped (for example redirect to the home page)
                    }
                  }];

// Close a Tanker session
await tanker.stop();