Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ message UserId {
}];
}

// Username is a user's unique handle on Flipcash. It uses the same character
// set as X — letters, digits and underscores — with the exception that it must
// be lowercase.
message Username {
string value = 1 [(validate.rules).string.pattern = "^[a-z0-9_]{2,15}$"];
}

message ChatId {
// value has the following structure:
// - 32 byte hash for DMs
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,20 @@ import "google/protobuf/timestamp.proto";
import "validate/validate.proto";

message UserProfile {
// The ID of the user this profile belongs to. Always set, so a caller that
// looked the profile up by username learns the user's ID from the response.
common.v1.UserId user_id = 9 [(validate.rules).message.required = true];

// Display name is the display name of the user (if found).
string display_name = 1 [(validate.rules).string = {
min_len: 0
max_len: 64
}];

// The user's username on Flipcash. Public, so it is returned for any user,
// not just the caller. Unset when the user hasn't claimed one yet.
common.v1.Username username = 8;

// Social profiles are links to external social accounts
repeated SocialProfile social_profiles = 2 [(validate.rules).repeated = {
min_items: 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,14 @@ service Profile {
}

message GetProfileRequest {
common.v1.UserId user_id = 1 [(validate.rules).message.required = true];
// The user whose profile is being fetched, identified either by their user
// ID or by their username. Exactly one must be set.
oneof identifier {
option (validate.required) = true;

common.v1.UserId user_id = 1;
common.v1.Username username = 3;
}

// Optional auth to retrieve private profile information for self
common.v1.Auth auth = 2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,9 @@ message Identifier {
oneof kind {
option (validate.required) = true;

common.v1.PhoneNumber phone = 1;
common.v1.UserId user_id = 2;
common.v1.PhoneNumber phone = 1;
common.v1.UserId user_id = 2;
common.v1.Username username = 3;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,18 @@ import Foundation
extension FlipClient {

public func fetchProfile(userID: UserID, owner: KeyPair) async throws -> Profile {
try await fetchProfile(.userID(userID), owner: owner)
}

/// Fetches the profile behind a claimed handle. The response carries the
/// user's id, so a caller holding only a handle learns it from the result.
public func fetchProfile(username: Username, owner: KeyPair) async throws -> Profile {
try await fetchProfile(.username(username), owner: owner)
}

private func fetchProfile(_ identifier: ProfileIdentifier, owner: KeyPair) async throws -> Profile {
try await withCheckedThrowingContinuation { c in
profileService.fetchProfile(userID: userID, owner: owner) { c.resume(with: $0) }
profileService.fetchProfile(identifier, owner: owner) { c.resume(with: $0) }
}
}

Expand Down
Loading