Page MenuHomePhabricator

D8407.id31145.diff
No OneTemporary

D8407.id31145.diff

diff --git a/keyserver/src/endpoints.js b/keyserver/src/endpoints.js
--- a/keyserver/src/endpoints.js
+++ b/keyserver/src/endpoints.js
@@ -178,6 +178,8 @@
updatePasswordRequestInputValidator,
updateUserAvatarResponderValidator,
updateUserSettingsInputValidator,
+ claimUsernameResponder,
+ claimUsernameResponseValidator,
} from './responders/user-responders.js';
import {
codeVerificationResponder,
@@ -533,6 +535,12 @@
logInResponseValidator,
[],
),
+ claim_username: createJSONResponder(
+ claimUsernameResponder,
+ ignoredArgumentValidator,
+ claimUsernameResponseValidator,
+ [],
+ ),
update_user_avatar: createJSONResponder(
updateUserAvatarResponder,
updateUserAvatarRequestValidator,
diff --git a/keyserver/src/responders/user-responders.js b/keyserver/src/responders/user-responders.js
--- a/keyserver/src/responders/user-responders.js
+++ b/keyserver/src/responders/user-responders.js
@@ -23,6 +23,7 @@
UpdatePasswordRequest,
UpdateUserSettingsRequest,
PolicyAcknowledgmentRequest,
+ ClaimUsernameResponse,
} from 'lib/types/account-types.js';
import {
userSettingsTypes,
@@ -36,6 +37,7 @@
type UpdateUserAvatarRequest,
} from 'lib/types/avatar-types.js';
import type {
+ ReservedUsernameMessage,
IdentityKeysBlob,
SignedIdentityKeysBlob,
} from 'lib/types/crypto-types.js';
@@ -113,6 +115,7 @@
fetchKnownUserInfos,
fetchLoggedInUserInfo,
fetchUserIDForEthereumAddress,
+ fetchUsername,
} from '../fetchers/user-fetchers.js';
import {
createNewAnonymousCookie,
@@ -129,6 +132,7 @@
updateUserSettings,
updateUserAvatar,
} from '../updaters/account-updaters.js';
+import { fetchOlmAccount } from '../updaters/olm-account-updater.js';
import { userSubscriptionUpdater } from '../updaters/user-subscription-updaters.js';
import { viewerAcknowledgmentUpdater } from '../updaters/viewer-acknowledgment-updater.js';
import { getOlmUtility } from '../utils/olm-utils.js';
@@ -730,6 +734,36 @@
return await updateUserAvatar(viewer, request);
}
+export const claimUsernameResponseValidator: TInterface<ClaimUsernameResponse> =
+ tShape<ClaimUsernameResponse>({
+ message: t.String,
+ signature: t.String,
+ });
+
+async function claimUsernameResponder(
+ viewer: Viewer,
+): Promise<ClaimUsernameResponse> {
+ const [username, accountInfo] = await Promise.all([
+ fetchUsername(viewer.userID),
+ fetchOlmAccount('content'),
+ ]);
+
+ if (!username) {
+ throw new ServerError('invalid_credentials');
+ }
+
+ const issuedAt = new Date().toISOString();
+ const reservedUsernameMessage: ReservedUsernameMessage = {
+ statement: 'This user is the owner of the following username',
+ payload: username,
+ issuedAt,
+ };
+ const message = JSON.stringify(reservedUsernameMessage);
+ const signature = accountInfo.account.sign(message);
+
+ return { message, signature };
+}
+
export {
userSubscriptionUpdateResponder,
passwordUpdateResponder,
@@ -744,4 +778,5 @@
updateUserSettingsResponder,
policyAcknowledgmentResponder,
updateUserAvatarResponder,
+ claimUsernameResponder,
};
diff --git a/lib/actions/user-actions.js b/lib/actions/user-actions.js
--- a/lib/actions/user-actions.js
+++ b/lib/actions/user-actions.js
@@ -9,6 +9,7 @@
RegisterInfo,
UpdateUserSettingsRequest,
PolicyAcknowledgmentRequest,
+ ClaimUsernameResponse,
} from '../types/account-types.js';
import type {
UpdateUserAvatarRequest,
@@ -62,6 +63,25 @@
return { currentUserInfo, preRequestUserState };
};
+const claimUsernameActionTypes = Object.freeze({
+ started: 'CLAIM_USERNAME_STARTED',
+ success: 'CLAIM_USERNAME_SUCCESS',
+ failed: 'CLAIM_USERNAME_FAILED',
+});
+const claimUsernameCallServerEndpointOptions = { timeout: 500 };
+const claimUsername =
+ (
+ callServerEndpoint: CallServerEndpoint,
+ ): (() => Promise<ClaimUsernameResponse>) =>
+ async () => {
+ const response = await callServerEndpoint(
+ 'claim_username',
+ {},
+ { ...claimUsernameCallServerEndpointOptions },
+ );
+ return response;
+ };
+
const deleteAccountActionTypes = Object.freeze({
started: 'DELETE_ACCOUNT_STARTED',
success: 'DELETE_ACCOUNT_SUCCESS',
@@ -327,6 +347,8 @@
export {
changeUserPasswordActionTypes,
changeUserPassword,
+ claimUsernameActionTypes,
+ claimUsername,
deleteAccount,
deleteAccountActionTypes,
getSessionPublicKeys,
diff --git a/lib/types/account-types.js b/lib/types/account-types.js
--- a/lib/types/account-types.js
+++ b/lib/types/account-types.js
@@ -203,3 +203,8 @@
tShape<DefaultNotificationPayload>({
default_user_notifications: t.maybe(t.enums.of(notificationTypeValues)),
});
+
+export type ClaimUsernameResponse = {
+ +message: string,
+ +signature: string,
+};
diff --git a/lib/types/crypto-types.js b/lib/types/crypto-types.js
--- a/lib/types/crypto-types.js
+++ b/lib/types/crypto-types.js
@@ -59,6 +59,11 @@
+statement: 'Remove the following username from reserved list',
+payload: string,
+issuedAt: string,
+ }
+ | {
+ +statement: 'This user is the owner of the following username',
+ +payload: string,
+ +issuedAt: string,
};
export const olmEncryptedMessageTypes = Object.freeze({
diff --git a/lib/types/endpoints.js b/lib/types/endpoints.js
--- a/lib/types/endpoints.js
+++ b/lib/types/endpoints.js
@@ -93,6 +93,7 @@
VERIFY_INVITE_LINK: 'verify_invite_link',
SIWE_NONCE: 'siwe_nonce',
SIWE_AUTH: 'siwe_auth',
+ CLAIM_USERNAME: 'claim_username',
UPDATE_USER_AVATAR: 'update_user_avatar',
UPLOAD_MEDIA_METADATA: 'upload_media_metadata',
SEARCH_MESSAGES: 'search_messages',
diff --git a/lib/types/redux-types.js b/lib/types/redux-types.js
--- a/lib/types/redux-types.js
+++ b/lib/types/redux-types.js
@@ -6,6 +6,7 @@
LogInResult,
RegisterResult,
DefaultNotificationPayload,
+ ClaimUsernameResponse,
} from './account-types.js';
import type {
ActivityUpdateSuccessPayload,
@@ -184,6 +185,22 @@
+payload: LogOutResult,
+loadingInfo: LoadingInfo,
}
+ | {
+ +type: 'CLAIM_USERNAME_STARTED',
+ +payload?: void,
+ +loadingInfo: LoadingInfo,
+ }
+ | {
+ +type: 'CLAIM_USERNAME_FAILED',
+ +error: true,
+ +payload: Error,
+ +loadingInfo: LoadingInfo,
+ }
+ | {
+ +type: 'CLAIM_USERNAME_SUCCESS',
+ +payload: ClaimUsernameResponse,
+ +loadingInfo: LoadingInfo,
+ }
| {
+type: 'DELETE_ACCOUNT_STARTED',
+payload?: void,

File Metadata

Mime Type
text/plain
Expires
Thu, Jan 9, 7:52 AM (9 h, 6 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2830525
Default Alt Text
D8407.id31145.diff (6 KB)

Event Timeline