org.whispersystems.signalservice.api.profiles.SignalServiceProfile Java Examples
The following examples show how to use
org.whispersystems.signalservice.api.profiles.SignalServiceProfile.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: SignalServiceMessageReceiver.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
public ProfileAndCredential retrieveProfile(SignalServiceAddress address, Optional<ProfileKey> profileKey, Optional<UnidentifiedAccess> unidentifiedAccess, SignalServiceProfile.RequestType requestType) throws NonSuccessfulResponseCodeException, PushNetworkException, VerificationFailedException { Optional<UUID> uuid = address.getUuid(); if (uuid.isPresent() && profileKey.isPresent()) { if (requestType == SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL) { return socket.retrieveVersionedProfileAndCredential(uuid.get(), profileKey.get(), unidentifiedAccess); } else { return new ProfileAndCredential(socket.retrieveVersionedProfile(uuid.get(), profileKey.get(), unidentifiedAccess), SignalServiceProfile.RequestType.PROFILE, Optional.absent()); } } else { return new ProfileAndCredential(socket.retrieveProfile(address, unidentifiedAccess), SignalServiceProfile.RequestType.PROFILE, Optional.absent()); } }
Example #2
Source File: Manager.java From signal-cli with GNU General Public License v3.0 | 6 votes |
private SignalServiceProfile getRecipientProfile(SignalServiceAddress address, Optional<UnidentifiedAccess> unidentifiedAccess) throws IOException { SignalServiceMessagePipe pipe = unidentifiedMessagePipe != null && unidentifiedAccess.isPresent() ? unidentifiedMessagePipe : messagePipe; if (pipe != null) { try { return pipe.getProfile(address, Optional.absent(), unidentifiedAccess, SignalServiceProfile.RequestType.PROFILE).getProfile(); } catch (IOException ignored) { } } SignalServiceMessageReceiver receiver = getMessageReceiver(); try { return receiver.retrieveProfile(address, Optional.absent(), unidentifiedAccess, SignalServiceProfile.RequestType.PROFILE).getProfile(); } catch (VerificationFailedException e) { throw new AssertionError(e); } }
Example #3
Source File: RetrieveProfileJob.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
private void handlePhoneNumberRecipient(Recipient recipient) throws IOException { ProfileAndCredential profileAndCredential = ProfileUtil.retrieveProfile(context, recipient, getRequestType(recipient)); SignalServiceProfile profile = profileAndCredential.getProfile(); ProfileKey recipientProfileKey = ProfileKeyUtil.profileKeyOrNull(recipient.getProfileKey()); if (recipientProfileKey == null) { Log.i(TAG, "No profile key available for " + recipient.getId()); } else { Log.i(TAG, "Profile key available for " + recipient.getId()); } setProfileName(recipient, profile.getName()); setProfileAvatar(recipient, profile.getAvatar()); if (FeatureFlags.usernames()) setUsername(recipient, profile.getUsername()); setProfileCapabilities(recipient, profile.getCapabilities()); setIdentityKey(recipient, profile.getIdentityKey()); setUnidentifiedAccessMode(recipient, profile.getUnidentifiedAccess(), profile.isUnrestrictedUnidentifiedAccess()); if (recipientProfileKey != null) { Optional<ProfileKeyCredential> profileKeyCredential = profileAndCredential.getProfileKeyCredential(); if (profileKeyCredential.isPresent()) { setProfileKeyCredential(recipient, recipientProfileKey, profileKeyCredential.get()); } } }
Example #4
Source File: PushServiceSocket.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
public ProfileAndCredential retrieveVersionedProfileAndCredential(UUID target, ProfileKey profileKey, Optional<UnidentifiedAccess> unidentifiedAccess) throws NonSuccessfulResponseCodeException, PushNetworkException, VerificationFailedException { ProfileKeyVersion profileKeyIdentifier = profileKey.getProfileKeyVersion(target); ProfileKeyCredentialRequestContext requestContext = clientZkProfileOperations.createProfileKeyCredentialRequestContext(random, target, profileKey); ProfileKeyCredentialRequest request = requestContext.getRequest(); String version = profileKeyIdentifier.serialize(); String credentialRequest = Hex.toStringCondensed(request.serialize()); String subPath = String.format("%s/%s/%s", target, version, credentialRequest); String response = makeServiceRequest(String.format(PROFILE_PATH, subPath), "GET", null, NO_HEADERS, unidentifiedAccess); try { SignalServiceProfile signalServiceProfile = JsonUtil.fromJson(response, SignalServiceProfile.class); ProfileKeyCredential profileKeyCredential = signalServiceProfile.getProfileKeyCredentialResponse() != null ? clientZkProfileOperations.receiveProfileKeyCredential(requestContext, signalServiceProfile.getProfileKeyCredentialResponse()) : null; return new ProfileAndCredential(signalServiceProfile, SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL, Optional.fromNullable(profileKeyCredential)); } catch (IOException e) { Log.w(TAG, e); throw new NonSuccessfulResponseCodeException("Unable to parse entity"); } }
Example #5
Source File: PushServiceSocket.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
public SignalServiceProfile retrieveVersionedProfile(UUID target, ProfileKey profileKey, Optional<UnidentifiedAccess> unidentifiedAccess) throws NonSuccessfulResponseCodeException, PushNetworkException { ProfileKeyVersion profileKeyIdentifier = profileKey.getProfileKeyVersion(target); String version = profileKeyIdentifier.serialize(); String subPath = String.format("%s/%s", target, version); String response = makeServiceRequest(String.format(PROFILE_PATH, subPath), "GET", null, NO_HEADERS, unidentifiedAccess); try { return JsonUtil.fromJson(response, SignalServiceProfile.class); } catch (IOException e) { Log.w(TAG, e); throw new NonSuccessfulResponseCodeException("Unable to parse entity"); } }
Example #6
Source File: AccountAttributes.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
public AccountAttributes(String signalingKey, int registrationId, boolean fetchesMessages, String pin, String registrationLock, byte[] unidentifiedAccessKey, boolean unrestrictedUnidentifiedAccess, SignalServiceProfile.Capabilities capabilities) { this.signalingKey = signalingKey; this.registrationId = registrationId; this.voice = true; this.video = true; this.fetchesMessages = fetchesMessages; this.pin = pin; this.registrationLock = registrationLock; this.unidentifiedAccessKey = unidentifiedAccessKey; this.unrestrictedUnidentifiedAccess = unrestrictedUnidentifiedAccess; this.capabilities = capabilities; }
Example #7
Source File: RefreshOwnProfileJob.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
@Override protected void onRun() throws Exception { if (!TextSecurePreferences.isPushRegistered(context) || TextUtils.isEmpty(TextSecurePreferences.getLocalNumber(context))) { Log.w(TAG, "Not yet registered!"); return; } Recipient self = Recipient.self(); ProfileAndCredential profileAndCredential = ProfileUtil.retrieveProfile(context, self, getRequestType(self)); SignalServiceProfile profile = profileAndCredential.getProfile(); setProfileName(profile.getName()); setProfileAvatar(profile.getAvatar()); setProfileCapabilities(profile.getCapabilities()); Optional<ProfileKeyCredential> profileKeyCredential = profileAndCredential.getProfileKeyCredential(); if (profileKeyCredential.isPresent()) { setProfileKeyCredential(self, ProfileKeyUtil.getSelfProfileKey(), profileKeyCredential.get()); } }
Example #8
Source File: ProfileUtil.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
@WorkerThread public static @NonNull ProfileAndCredential retrieveProfile(@NonNull Context context, @NonNull Recipient recipient, @NonNull SignalServiceProfile.RequestType requestType) throws IOException { SignalServiceAddress address = RecipientUtil.toSignalServiceAddress(context, recipient); Optional<UnidentifiedAccess> unidentifiedAccess = getUnidentifiedAccess(context, recipient); Optional<ProfileKey> profileKey = ProfileKeyUtil.profileKeyOptional(recipient.getProfileKey()); ProfileAndCredential profile; try { profile = retrieveProfileInternal(address, profileKey, unidentifiedAccess, requestType); } catch (NonSuccessfulResponseCodeException e) { if (unidentifiedAccess.isPresent()) { profile = retrieveProfileInternal(address, profileKey, Optional.absent(), requestType); } else { throw e; } } return profile; }
Example #9
Source File: UsernameUtil.java From mollyim-android with GNU General Public License v3.0 | 6 votes |
@WorkerThread public static @NonNull Optional<UUID> fetchUuidForUsername(@NonNull Context context, @NonNull String username) { Optional<RecipientId> localId = DatabaseFactory.getRecipientDatabase(context).getByUsername(username); if (localId.isPresent()) { Recipient recipient = Recipient.resolved(localId.get()); if (recipient.getUuid().isPresent()) { Log.i(TAG, "Found username locally -- using associated UUID."); return recipient.getUuid(); } else { Log.w(TAG, "Found username locally, but it had no associated UUID! Clearing it."); DatabaseFactory.getRecipientDatabase(context).clearUsernameIfExists(username); } } try { Log.d(TAG, "No local user with this username. Searching remotely."); SignalServiceProfile profile = ApplicationDependencies.getSignalServiceMessageReceiver().retrieveProfileByUsername(username, Optional.absent()); return Optional.fromNullable(profile.getUuid()); } catch (IOException e) { return Optional.absent(); } }
Example #10
Source File: EditSelfProfileRepository.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
@WorkerThread private @NonNull Optional<String> getUsernameInternal() { try { SignalServiceProfile profile = ProfileUtil.retrieveProfile(context, Recipient.self(), SignalServiceProfile.RequestType.PROFILE).getProfile(); TextSecurePreferences.setLocalUsername(context, profile.getUsername()); DatabaseFactory.getRecipientDatabase(context).setUsername(Recipient.self().getId(), profile.getUsername()); } catch (IOException e) { Log.w(TAG, "Failed to retrieve username remotely! Using locally-cached version."); } return Optional.fromNullable(TextSecurePreferences.getLocalUsername(context)); }
Example #11
Source File: Manager.java From signal-cli with GNU General Public License v3.0 | 5 votes |
private static SignalProfile decryptProfile(SignalServiceProfile encryptedProfile, ProfileKey profileKey) throws IOException { ProfileCipher profileCipher = new ProfileCipher(profileKey); try { return new SignalProfile( encryptedProfile.getIdentityKey(), encryptedProfile.getName() == null ? null : new String(profileCipher.decryptName(Base64.decode(encryptedProfile.getName()))), encryptedProfile.getAvatar(), encryptedProfile.getUnidentifiedAccess() == null || !profileCipher.verifyUnidentifiedAccess(Base64.decode(encryptedProfile.getUnidentifiedAccess())) ? null : encryptedProfile.getUnidentifiedAccess(), encryptedProfile.isUnrestrictedUnidentifiedAccess() ); } catch (InvalidCiphertextException e) { return null; } }
Example #12
Source File: PushServiceSocket.java From libsignal-service-java with GNU General Public License v3.0 | 5 votes |
public SignalServiceProfile retrieveProfile(SignalServiceAddress target, Optional<UnidentifiedAccess> unidentifiedAccess) throws NonSuccessfulResponseCodeException, PushNetworkException { try { String response = makeServiceRequest(String.format(PROFILE_PATH, target.getIdentifier()), "GET", null, NO_HEADERS, unidentifiedAccess); return JsonUtil.fromJson(response, SignalServiceProfile.class); } catch (IOException e) { Log.w(TAG, e); throw new NonSuccessfulResponseCodeException("Unable to parse entity"); } }
Example #13
Source File: SignalServiceMessagePipe.java From libsignal-service-java with GNU General Public License v3.0 | 5 votes |
public SignalServiceProfile getProfile(SignalServiceAddress address, Optional<UnidentifiedAccess> unidentifiedAccess) throws IOException { try { List<String> headers = new LinkedList<>(); if (unidentifiedAccess.isPresent()) { headers.add("Unidentified-Access-Key:" + Base64.encodeBytes(unidentifiedAccess.get().getUnidentifiedAccessKey())); } WebSocketRequestMessage requestMessage = WebSocketRequestMessage.newBuilder() .setId(SecureRandom.getInstance("SHA1PRNG").nextLong()) .setVerb("GET") .setPath(String.format("/v1/profile/%s", address.getIdentifier())) .addAllHeaders(headers) .build(); Pair<Integer, String> response = websocket.sendRequest(requestMessage).get(10, TimeUnit.SECONDS); if (response.first() < 200 || response.first() >= 300) { throw new IOException("Non-successful response: " + response.first()); } return JsonUtil.fromJson(response.second(), SignalServiceProfile.class); } catch (NoSuchAlgorithmException nsae) { throw new AssertionError(nsae); } catch (InterruptedException | ExecutionException | TimeoutException e) { throw new IOException(e); } }
Example #14
Source File: JsonProfile.java From signald with GNU General Public License v3.0 | 5 votes |
JsonProfile(SignalServiceProfile p, byte[] profileKey) throws IOException, InvalidCiphertextException { ProfileCipher profileCipher = new ProfileCipher(profileKey); name = new String(profileCipher.decryptName(Base64.decode(p.getName()))); identity_key = p.getIdentityKey(); avatar = p.getAvatar(); unidentified_access = p.getUnidentifiedAccess(); if (p.isUnrestrictedUnidentifiedAccess()) { unrestricted_unidentified_access = true; } }
Example #15
Source File: RetrieveProfileJob.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
private void setProfileCapabilities(@NonNull Recipient recipient, @Nullable SignalServiceProfile.Capabilities capabilities) { if (capabilities == null) { return; } DatabaseFactory.getRecipientDatabase(context).setCapabilities(recipient.getId(), capabilities); }
Example #16
Source File: RefreshOwnProfileJob.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
private void setProfileCapabilities(@Nullable SignalServiceProfile.Capabilities capabilities) { if (capabilities == null) { return; } DatabaseFactory.getRecipientDatabase(context).setCapabilities(Recipient.self().getId(), capabilities); }
Example #17
Source File: RecipientDatabase.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
public void setCapabilities(@NonNull RecipientId id, @NonNull SignalServiceProfile.Capabilities capabilities) { ContentValues values = new ContentValues(2); values.put(UUID_CAPABILITY, Recipient.Capability.fromBoolean(capabilities.isUuid()).serialize()); values.put(GROUPS_V2_CAPABILITY, Recipient.Capability.fromBoolean(capabilities.isGv2()).serialize()); if (update(id, values)) { Recipient.live(id).refresh(); } }
Example #18
Source File: DirectoryHelperV1.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
private static boolean isUuidRegistered(@NonNull Context context, @NonNull Recipient recipient) throws IOException { try { ProfileUtil.retrieveProfile(context, recipient, SignalServiceProfile.RequestType.PROFILE); return true; } catch (NotFoundException e) { return false; } }
Example #19
Source File: PushServiceSocket.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
public SignalServiceProfile retrieveProfileByUsername(String username, Optional<UnidentifiedAccess> unidentifiedAccess) throws NonSuccessfulResponseCodeException, PushNetworkException { String response = makeServiceRequest(String.format(PROFILE_USERNAME_PATH, username), "GET", null, NO_HEADERS, unidentifiedAccess); try { return JsonUtil.fromJson(response, SignalServiceProfile.class); } catch (IOException e) { Log.w(TAG, e); throw new NonSuccessfulResponseCodeException("Unable to parse entity"); } }
Example #20
Source File: PushServiceSocket.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
public SignalServiceProfile retrieveProfile(SignalServiceAddress target, Optional<UnidentifiedAccess> unidentifiedAccess) throws NonSuccessfulResponseCodeException, PushNetworkException { String response = makeServiceRequest(String.format(PROFILE_PATH, target.getIdentifier()), "GET", null, NO_HEADERS, unidentifiedAccess); try { return JsonUtil.fromJson(response, SignalServiceProfile.class); } catch (IOException e) { Log.w(TAG, e); throw new NonSuccessfulResponseCodeException("Unable to parse entity"); } }
Example #21
Source File: PushServiceSocket.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
public void setAccountAttributes(String signalingKey, int registrationId, boolean fetchesMessages, String pin, String registrationLock, byte[] unidentifiedAccessKey, boolean unrestrictedUnidentifiedAccess, SignalServiceProfile.Capabilities capabilities) throws IOException { if (registrationLock != null && pin != null) { throw new AssertionError("Pin should be null if registrationLock is set."); } AccountAttributes accountAttributes = new AccountAttributes(signalingKey, registrationId, fetchesMessages, pin, registrationLock, unidentifiedAccessKey, unrestrictedUnidentifiedAccess, capabilities); makeServiceRequest(SET_ACCOUNT_ATTRIBUTES, "PUT", JsonUtil.toJson(accountAttributes)); }
Example #22
Source File: PushServiceSocket.java From mollyim-android with GNU General Public License v3.0 | 5 votes |
public VerifyAccountResponse verifyAccountCode(String verificationCode, String signalingKey, int registrationId, boolean fetchesMessages, String pin, String registrationLock, byte[] unidentifiedAccessKey, boolean unrestrictedUnidentifiedAccess, SignalServiceProfile.Capabilities capabilities) throws IOException { AccountAttributes signalingKeyEntity = new AccountAttributes(signalingKey, registrationId, fetchesMessages, pin, registrationLock, unidentifiedAccessKey, unrestrictedUnidentifiedAccess, capabilities); String requestBody = JsonUtil.toJson(signalingKeyEntity); String responseBody = makeServiceRequest(String.format(VERIFY_ACCOUNT_CODE_PATH, verificationCode), "PUT", requestBody); return JsonUtil.fromJson(responseBody, VerifyAccountResponse.class); }
Example #23
Source File: RefreshOwnProfileJob.java From mollyim-android with GNU General Public License v3.0 | 4 votes |
private static SignalServiceProfile.RequestType getRequestType(@NonNull Recipient recipient) { return FeatureFlags.versionedProfiles() && !recipient.hasProfileKeyCredential() ? SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL : SignalServiceProfile.RequestType.PROFILE; }
Example #24
Source File: AccountAttributes.java From mollyim-android with GNU General Public License v3.0 | 4 votes |
public SignalServiceProfile.Capabilities getCapabilities() { return capabilities; }
Example #25
Source File: RetrieveProfileJob.java From mollyim-android with GNU General Public License v3.0 | 4 votes |
private static SignalServiceProfile.RequestType getRequestType(@NonNull Recipient recipient) { return FeatureFlags.versionedProfiles() && !recipient.hasProfileKeyCredential() ? SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL : SignalServiceProfile.RequestType.PROFILE; }
Example #26
Source File: Manager.java From signald with GNU General Public License v3.0 | 4 votes |
public SignalServiceProfile getProfile(String number) throws IOException { final SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(serviceConfiguration, accountData.username, accountData.password, accountData.deviceId, accountData.signalingKey, USER_AGENT, null, sleepTimer); return messageReceiver.retrieveProfile(new SignalServiceAddress(number), Optional.<UnidentifiedAccess>absent()); }
Example #27
Source File: SignalServiceMessageReceiver.java From libsignal-service-java with GNU General Public License v3.0 | 4 votes |
public SignalServiceProfile retrieveProfile(SignalServiceAddress address, Optional<UnidentifiedAccess> unidentifiedAccess) throws IOException { return socket.retrieveProfile(address, unidentifiedAccess); }
Example #28
Source File: SignalServiceMessagePipe.java From mollyim-android with GNU General Public License v3.0 | 4 votes |
public ProfileAndCredential getProfile(SignalServiceAddress address, Optional<ProfileKey> profileKey, Optional<UnidentifiedAccess> unidentifiedAccess, SignalServiceProfile.RequestType requestType) throws IOException { try { List<String> headers = new LinkedList<>(); if (unidentifiedAccess.isPresent()) { headers.add("Unidentified-Access-Key:" + Base64.encodeBytes(unidentifiedAccess.get().getUnidentifiedAccessKey())); } Optional<UUID> uuid = address.getUuid(); SecureRandom random = new SecureRandom(); ProfileKeyCredentialRequestContext requestContext = null; WebSocketRequestMessage.Builder builder = WebSocketRequestMessage.newBuilder() .setId(random.nextLong()) .setVerb("GET") .addAllHeaders(headers); if (uuid.isPresent() && profileKey.isPresent()) { UUID target = uuid.get(); ProfileKeyVersion profileKeyIdentifier = profileKey.get().getProfileKeyVersion(target); String version = profileKeyIdentifier.serialize(); if (requestType == SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL) { requestContext = clientZkProfile.createProfileKeyCredentialRequestContext(random, target, profileKey.get()); ProfileKeyCredentialRequest request = requestContext.getRequest(); String credentialRequest = Hex.toStringCondensed(request.serialize()); builder.setPath(String.format("/v1/profile/%s/%s/%s", target, version, credentialRequest)); } else { builder.setPath(String.format("/v1/profile/%s/%s", target, version)); } } else { builder.setPath(String.format("/v1/profile/%s", address.getIdentifier())); } WebSocketRequestMessage requestMessage = builder.build(); WebsocketResponse response = websocket.sendRequest(requestMessage).get(10, TimeUnit.SECONDS); if (response.getStatus() < 200 || response.getStatus() >= 300) { throw new IOException("Non-successful response: " + response.getStatus()); } SignalServiceProfile signalServiceProfile = JsonUtil.fromJson(response.getBody(), SignalServiceProfile.class); ProfileKeyCredential profileKeyCredential = requestContext != null && signalServiceProfile.getProfileKeyCredentialResponse() != null ? clientZkProfile.receiveProfileKeyCredential(requestContext, signalServiceProfile.getProfileKeyCredentialResponse()) : null; return new ProfileAndCredential(signalServiceProfile, requestType, Optional.fromNullable(profileKeyCredential)); } catch (InterruptedException | ExecutionException | TimeoutException | VerificationFailedException e) { throw new IOException(e); } }
Example #29
Source File: SignalServiceMessageReceiver.java From mollyim-android with GNU General Public License v3.0 | 4 votes |
public SignalServiceProfile retrieveProfileByUsername(String username, Optional<UnidentifiedAccess> unidentifiedAccess) throws IOException { return socket.retrieveProfileByUsername(username, unidentifiedAccess); }
Example #30
Source File: SignalServiceAccountManager.java From mollyim-android with GNU General Public License v3.0 | 3 votes |
/** * Verify a Signal Service account with a received SMS or voice verification code. * * @param verificationCode The verification code received via SMS or Voice * (see {@link #requestSmsVerificationCode} and * {@link #requestVoiceVerificationCode}). * @param signalingKey 52 random bytes. A 32 byte AES key and a 20 byte Hmac256 key, * concatenated. * @param signalProtocolRegistrationId A random 14-bit number that identifies this Signal install. * This value should remain consistent across registrations for the * same install, but probabilistically differ across registrations * for separate installs. * @param pin Deprecated, only supply the pin if you did not find a registrationLock on KBS. * @param registrationLock Only supply if found on KBS. * @return The UUID of the user that was registered. * @throws IOException */ public VerifyAccountResponse verifyAccountWithCode(String verificationCode, String signalingKey, int signalProtocolRegistrationId, boolean fetchesMessages, String pin, String registrationLock, byte[] unidentifiedAccessKey, boolean unrestrictedUnidentifiedAccess, SignalServiceProfile.Capabilities capabilities) throws IOException { return this.pushServiceSocket.verifyAccountCode(verificationCode, signalingKey, signalProtocolRegistrationId, fetchesMessages, pin, registrationLock, unidentifiedAccessKey, unrestrictedUnidentifiedAccess, capabilities); }