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
1 change: 0 additions & 1 deletion cassandra-schema.cql
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,6 @@ CREATE TABLE brig_test.team_invitation (
created_by uuid,
email text,
name text,
phone text,
role int,
PRIMARY KEY (team, id)
) WITH CLUSTERING ORDER BY (id ASC)
Expand Down
1 change: 1 addition & 0 deletions changelog.d/0-release-notes/WPB-8707
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A schema migration drops column 'phone' from Brig's 'team_invitation' table. Previous releases were still reading this column. As there is no Team Settings UI action to enter a phone number, this reading will not miss to read actual phone numbers. Therefore, during deployment this will lead to benign 5xx errors.
1 change: 1 addition & 0 deletions changelog.d/1-api-changes/WPB-8707
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
All the phone number-based functionality is removed from the client API v6
2 changes: 1 addition & 1 deletion integration/test/Test/User.hs
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,4 @@ testActivateAccountWithPhoneV5 = do
let reqBody = Aeson.object ["phone" .= phone]
activateUserV5 dom reqBody `bindResponse` \resp -> do
resp.status `shouldMatchInt` 400
resp.json %. "label" `shouldMatch` "invalid-phone"
resp.json %. "label" `shouldMatch` "bad-request"
8 changes: 5 additions & 3 deletions libs/wire-api/src/Wire/API/Routes/Public/Brig.hs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,7 @@ type SelfAPI =
:<|> Named
"change-phone"
( Summary "Change your phone number."
:> Until 'V6
:> ZUser
:> ZConn
:> "self"
Expand All @@ -356,6 +357,7 @@ type SelfAPI =
Named
"remove-phone"
( Summary "Remove your phone number."
:> Until 'V6
:> Description
"Your phone number can only be removed if you also have an \
\email address and a password."
Expand Down Expand Up @@ -503,7 +505,7 @@ type AccountAPI =
-- - UserIdentityUpdated event to the user, if email or phone get activated
:<|> Named
"get-activate"
( Summary "Activate (i.e. confirm) an email address or phone number."
( Summary "Activate (i.e. confirm) an email address."
:> MakesFederatedCall 'Brig "send-connection-action"
:> Description "See also 'POST /activate' which has a larger feature set."
:> CanThrow 'UserKeyExists
Expand All @@ -527,7 +529,7 @@ type AccountAPI =
-- - UserIdentityUpdated event to the user, if email or phone get activated
:<|> Named
"post-activate"
( Summary "Activate (i.e. confirm) an email address or phone number."
( Summary "Activate (i.e. confirm) an email address."
:> Description
"Activation only succeeds once and the number of \
\failed attempts for a valid key is limited."
Expand All @@ -551,7 +553,6 @@ type AccountAPI =
( Summary "Send (or resend) an email activation code."
:> CanThrow 'UserKeyExists
:> CanThrow 'InvalidEmail
:> CanThrow 'InvalidPhone
:> CanThrow 'BlacklistedEmail
:> CanThrow 'CustomerExtensionBlockedDomain
:> "activate"
Expand Down Expand Up @@ -1417,6 +1418,7 @@ type AuthAPI =
"send-login-code"
( "login"
:> "send"
:> Until 'V6
:> Summary "Send a login code to a verified phone number"
:> Description
"This operation generates and sends a login code via sms for phone login.\
Expand Down
30 changes: 13 additions & 17 deletions libs/wire-api/src/Wire/API/Team/Invitation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,18 @@ import Wire.API.Error.Brig
import Wire.API.Locale (Locale)
import Wire.API.Routes.MultiVerb
import Wire.API.Team.Role (Role, defaultRole)
import Wire.API.User.Identity (Email, Phone)
import Wire.API.User.Identity (Email)
import Wire.API.User.Profile (Name)
import Wire.Arbitrary (Arbitrary, GenericUniform (..))

--------------------------------------------------------------------------------
-- InvitationRequest

data InvitationRequest = InvitationRequest
{ irLocale :: Maybe Locale,
irRole :: Maybe Role,
irInviteeName :: Maybe Name,
irInviteeEmail :: Email,
irInviteePhone :: Maybe Phone
{ locale :: Maybe Locale,
role :: Maybe Role,
inviteeName :: Maybe Name,
inviteeEmail :: Email
}
deriving stock (Eq, Show, Generic)
deriving (Arbitrary) via (GenericUniform InvitationRequest)
Expand All @@ -66,16 +65,14 @@ instance ToSchema InvitationRequest where
schema =
objectWithDocModifier "InvitationRequest" (description ?~ "A request to join a team on Wire.") $
InvitationRequest
<$> irLocale
<$> locale
.= optFieldWithDocModifier "locale" (description ?~ "Locale to use for the invitation.") (maybeWithDefault A.Null schema)
<*> irRole
<*> role
.= optFieldWithDocModifier "role" (description ?~ "Role of the invitee (invited user).") (maybeWithDefault A.Null schema)
<*> irInviteeName
<*> inviteeName
.= optFieldWithDocModifier "name" (description ?~ "Name of the invitee (1 - 128 characters).") (maybeWithDefault A.Null schema)
<*> irInviteeEmail
<*> inviteeEmail
.= fieldWithDocModifier "email" (description ?~ "Email of the invitee.") schema
<*> irInviteePhone
.= optFieldWithDocModifier "phone" (description ?~ "Phone number of the invitee, in the E.164 format.") (maybeWithDefault A.Null schema)

--------------------------------------------------------------------------------
-- Invitation
Expand All @@ -90,7 +87,6 @@ data Invitation = Invitation
inCreatedBy :: Maybe UserId,
inInviteeEmail :: Email,
inInviteeName :: Maybe Name,
inInviteePhone :: Maybe Phone,
inInviteeUrl :: Maybe (URIRef Absolute)
}
deriving stock (Eq, Show, Generic)
Expand All @@ -99,8 +95,10 @@ data Invitation = Invitation

instance ToSchema Invitation where
schema =
objectWithDocModifier "Invitation" (description ?~ "An invitation to join a team on Wire") $
Invitation
objectWithDocModifier
"Invitation"
(description ?~ "An invitation to join a team on Wire")
$ Invitation
<$> inTeam
.= fieldWithDocModifier "team" (description ?~ "Team ID of the inviting team") schema
<*> inRole
Expand All @@ -116,8 +114,6 @@ instance ToSchema Invitation where
.= fieldWithDocModifier "email" (description ?~ "Email of the invitee") schema
<*> inInviteeName
.= optFieldWithDocModifier "name" (description ?~ "Name of the invitee (1 - 128 characters)") (maybeWithDefault A.Null schema)
<*> inInviteePhone
.= optFieldWithDocModifier "phone" (description ?~ "Phone number of the invitee, in the E.164 format") (maybeWithDefault A.Null schema)
<*> (fmap (TE.decodeUtf8 . serializeURIRef') . inInviteeUrl)
.= optFieldWithDocModifier "url" (description ?~ "URL of the invitation link to be sent to the invitee") (maybeWithDefault A.Null urlSchema)
where
Expand Down
20 changes: 0 additions & 20 deletions libs/wire-api/src/Wire/API/User.hs
Original file line number Diff line number Diff line change
Expand Up @@ -948,12 +948,10 @@ newUserFromSpar new =
{ newUserDisplayName = newUserSparDisplayName new,
newUserUUID = Just $ newUserSparUUID new,
newUserIdentity = Just $ SSOIdentity (newUserSparSSOId new) Nothing,
newUserPhone = Nothing,
newUserPict = Nothing,
newUserAssets = [],
newUserAccentId = Nothing,
newUserEmailCode = Nothing,
newUserPhoneCode = Nothing,
newUserOrigin = Just . NewUserOriginTeamUser . NewTeamMemberSSO $ newUserSparTeamId new,
newUserLabel = Nothing,
newUserPassword = Nothing,
Expand All @@ -968,13 +966,11 @@ data NewUser = NewUser
-- | use this as 'UserId' (if 'Nothing', call 'Data.UUID.nextRandom').
newUserUUID :: Maybe UUID,
newUserIdentity :: Maybe UserIdentity,
newUserPhone :: Maybe Phone,
-- | DEPRECATED
newUserPict :: Maybe Pict,
newUserAssets :: [Asset],
newUserAccentId :: Maybe ColourId,
newUserEmailCode :: Maybe ActivationCode,
newUserPhoneCode :: Maybe ActivationCode,
newUserOrigin :: Maybe NewUserOrigin,
newUserLabel :: Maybe CookieLabel,
newUserLocale :: Maybe Locale,
Expand All @@ -992,12 +988,10 @@ emptyNewUser name =
{ newUserDisplayName = name,
newUserUUID = Nothing,
newUserIdentity = Nothing,
newUserPhone = Nothing,
newUserPict = Nothing,
newUserAssets = [],
newUserAccentId = Nothing,
newUserEmailCode = Nothing,
newUserPhoneCode = Nothing,
newUserOrigin = Nothing,
newUserLabel = Nothing,
newUserLocale = Nothing,
Expand All @@ -1015,16 +1009,12 @@ data NewUserRaw = NewUserRaw
{ newUserRawDisplayName :: Name,
newUserRawUUID :: Maybe UUID,
newUserRawEmail :: Maybe Email,
-- | This is deprecated and it should always be 'Nothing'.
newUserRawPhone :: Maybe Phone,
newUserRawSSOId :: Maybe UserSSOId,
-- | DEPRECATED
newUserRawPict :: Maybe Pict,
newUserRawAssets :: [Asset],
newUserRawAccentId :: Maybe ColourId,
newUserRawEmailCode :: Maybe ActivationCode,
-- | This is deprecated and it should always be 'Nothing'.
newUserRawPhoneCode :: Maybe ActivationCode,
newUserRawInvitationCode :: Maybe InvitationCode,
newUserRawTeamCode :: Maybe InvitationCode,
newUserRawTeam :: Maybe BindingNewTeamUser,
Expand All @@ -1046,8 +1036,6 @@ newUserRawObjectSchema =
.= maybe_ (optField "uuid" genericToSchema)
<*> newUserRawEmail
.= maybe_ (optField "email" schema)
<*> newUserRawPhone
.= maybe_ (optField "phone" schema)
<*> newUserRawSSOId
.= maybe_ (optField "sso_id" genericToSchema)
<*> newUserRawPict
Expand All @@ -1058,8 +1046,6 @@ newUserRawObjectSchema =
.= maybe_ (optField "accent_id" schema)
<*> newUserRawEmailCode
.= maybe_ (optField "email_code" schema)
<*> newUserRawPhoneCode
.= maybe_ (optField "phone_code" schema)
<*> newUserRawInvitationCode
.= maybe_ (optField "invitation_code" schema)
<*> newUserRawTeamCode
Expand Down Expand Up @@ -1092,13 +1078,11 @@ newUserToRaw NewUser {..} =
{ newUserRawDisplayName = newUserDisplayName,
newUserRawUUID = newUserUUID,
newUserRawEmail = emailIdentity =<< newUserIdentity,
newUserRawPhone = newUserPhone,
newUserRawSSOId = ssoIdentity =<< newUserIdentity,
newUserRawPict = newUserPict,
newUserRawAssets = newUserAssets,
newUserRawAccentId = newUserAccentId,
newUserRawEmailCode = newUserEmailCode,
newUserRawPhoneCode = newUserPhoneCode,
newUserRawInvitationCode = newUserOriginInvitationCode =<< newUserOrigin,
newUserRawTeamCode = newTeamUserCode =<< maybeOriginNTU,
newUserRawTeam = newTeamUserCreator =<< maybeOriginNTU,
Expand Down Expand Up @@ -1131,12 +1115,10 @@ newUserFromRaw NewUserRaw {..} = do
{ newUserDisplayName = newUserRawDisplayName,
newUserUUID = newUserRawUUID,
newUserIdentity = identity,
newUserPhone = newUserRawPhone,
newUserPict = newUserRawPict,
newUserAssets = newUserRawAssets,
newUserAccentId = newUserRawAccentId,
newUserEmailCode = newUserRawEmailCode,
newUserPhoneCode = newUserRawPhoneCode,
newUserOrigin = origin,
newUserLabel = newUserRawLabel,
newUserLocale = newUserRawLocale,
Expand All @@ -1150,15 +1132,13 @@ newUserFromRaw NewUserRaw {..} = do
instance Arbitrary NewUser where
arbitrary = do
newUserIdentity <- arbitrary
newUserPhone <- arbitrary
newUserOrigin <- genUserOrigin newUserIdentity
newUserDisplayName <- arbitrary
newUserUUID <- QC.elements [Just nil, Nothing]
newUserPict <- arbitrary
newUserAssets <- arbitrary
newUserAccentId <- arbitrary
newUserEmailCode <- arbitrary
newUserPhoneCode <- arbitrary
newUserLabel <- arbitrary
newUserLocale <- arbitrary
newUserPassword <- genUserPassword newUserIdentity newUserOrigin
Expand Down
82 changes: 26 additions & 56 deletions libs/wire-api/src/Wire/API/User/Activation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import Data.OpenApi (ToParamSchema)
import Data.OpenApi qualified as S
import Data.Schema
import Data.Text.Ascii
import Data.Tuple.Extra (fst3, snd3, thd3)
import Imports
import Servant (FromHttpApiData (..))
import Wire.API.Locale
Expand All @@ -59,8 +58,6 @@ import Wire.Arbitrary (Arbitrary, GenericUniform (..))
data ActivationTarget
= -- | An opaque key for some email awaiting activation.
ActivateKey ActivationKey
| -- | A known phone number awaiting activation.
ActivatePhone Phone
| -- | A known email address awaiting activation.
ActivateEmail Email
deriving stock (Eq, Show, Generic)
Expand All @@ -69,7 +66,6 @@ data ActivationTarget
instance ToByteString ActivationTarget where
builder (ActivateKey k) = builder k
builder (ActivateEmail e) = builder e
builder (ActivatePhone p) = builder p

-- | An opaque identifier of a 'UserKey' awaiting activation.
newtype ActivationKey = ActivationKey
Expand Down Expand Up @@ -142,33 +138,29 @@ instance ToSchema Activate where
\cookies or tokens on success but failures still count \
\towards the maximum failure count."

maybeActivationTargetObjectSchema :: ObjectSchemaP SwaggerDoc (Maybe ActivationKey, Maybe Phone, Maybe Email) ActivationTarget
maybeActivationTargetObjectSchema :: ObjectSchemaP SwaggerDoc (Maybe ActivationKey, Maybe Email) ActivationTarget
maybeActivationTargetObjectSchema =
withParser activationTargetTupleObjectSchema maybeActivationTargetTargetFromTuple
where
activationTargetTupleObjectSchema :: ObjectSchema SwaggerDoc (Maybe ActivationKey, Maybe Phone, Maybe Email)
activationTargetTupleObjectSchema :: ObjectSchema SwaggerDoc (Maybe ActivationKey, Maybe Email)
activationTargetTupleObjectSchema =
(,,)
<$> fst3 .= maybe_ (optFieldWithDocModifier "key" keyDocs schema)
<*> snd3 .= maybe_ (optFieldWithDocModifier "phone" phoneDocs schema)
<*> thd3 .= maybe_ (optFieldWithDocModifier "email" emailDocs schema)
(,)
<$> fst .= maybe_ (optFieldWithDocModifier "key" keyDocs schema)
<*> snd .= maybe_ (optFieldWithDocModifier "email" emailDocs schema)
where
keyDocs = description ?~ "An opaque key to activate, as it was sent by the API."
phoneDocs = description ?~ "A known phone number to activate."
emailDocs = description ?~ "A known email address to activate."

maybeActivationTargetTargetFromTuple :: (Maybe ActivationKey, Maybe Phone, Maybe Email) -> Parser ActivationTarget
maybeActivationTargetTargetFromTuple :: (Maybe ActivationKey, Maybe Email) -> Parser ActivationTarget
maybeActivationTargetTargetFromTuple = \case
(Just key, _, _) -> pure $ ActivateKey key
(_, _, Just email) -> pure $ ActivateEmail email
(_, Just phone, _) -> pure $ ActivatePhone phone
_ -> fail "key, email or phone must be present"
(Just key, _) -> pure $ ActivateKey key
(_, Just email) -> pure $ ActivateEmail email
_ -> fail "key or email must be present"

maybeActivationTargetToTuple :: ActivationTarget -> (Maybe ActivationKey, Maybe Phone, Maybe Email)
maybeActivationTargetToTuple :: ActivationTarget -> (Maybe ActivationKey, Maybe Email)
maybeActivationTargetToTuple = \case
ActivateKey key -> (Just key, Nothing, Nothing)
ActivatePhone phone -> (Nothing, Just phone, Nothing)
ActivateEmail email -> (Nothing, Nothing, Just email)
ActivateKey key -> (Just key, Nothing)
ActivateEmail email -> (Nothing, Just email)

-- | Information returned as part of a successful activation.
data ActivationResponse = ActivationResponse
Expand All @@ -191,13 +183,11 @@ instance ToSchema ActivationResponse where
--------------------------------------------------------------------------------
-- SendActivationCode

-- | Payload for a request to (re-)send an activation code
-- for a phone number or e-mail address. If a phone is used,
-- one can also request a call instead of SMS.
-- | Payload for a request to (re-)send an activation code for an e-mail
-- address.
data SendActivationCode = SendActivationCode
{ saUserKey :: Either Email Phone,
saLocale :: Maybe Locale,
saCall :: Bool
{ emailKey :: Email,
locale :: Maybe Locale
}
deriving stock (Eq, Show, Generic)
deriving (Arbitrary) via (GenericUniform SendActivationCode)
Expand All @@ -207,37 +197,17 @@ instance ToSchema SendActivationCode where
schema =
objectWithDocModifier "SendActivationCode" objectDesc $
SendActivationCode
<$> (maybeUserKeyToTuple . saUserKey) .= userKeyObjectSchema
<*> saLocale .= maybe_ (optFieldWithDocModifier "locale" (description ?~ "Locale to use for the activation code template.") schema)
<*> saCall .= (fromMaybe False <$> optFieldWithDocModifier "voice_call" (description ?~ "Request the code with a call instead (default is SMS).") schema)
<$> emailKey .= field "email" schema
<*> locale
.= maybe_
( optFieldWithDocModifier
"locale"
( description ?~ "Locale to use for the activation code template."
)
schema
)
where
maybeUserKeyToTuple :: Either Email Phone -> (Maybe Email, Maybe Phone)
maybeUserKeyToTuple = \case
Left email -> (Just email, Nothing)
Right phone -> (Nothing, Just phone)

objectDesc :: NamedSwaggerDoc -> NamedSwaggerDoc
objectDesc =
description
?~ "Data for requesting an email or phone activation code to be sent. \
\One of 'email' or 'phone' must be present."

userKeyObjectSchema :: ObjectSchemaP SwaggerDoc (Maybe Email, Maybe Phone) (Either Email Phone)
userKeyObjectSchema =
withParser userKeyTupleObjectSchema maybeUserKeyFromTuple
where
userKeyTupleObjectSchema :: ObjectSchema SwaggerDoc (Maybe Email, Maybe Phone)
userKeyTupleObjectSchema =
(,)
<$> fst .= maybe_ (optFieldWithDocModifier "email" phoneDocs schema)
<*> snd .= maybe_ (optFieldWithDocModifier "phone" emailDocs schema)
where
emailDocs = description ?~ "Email address to send the code to."
phoneDocs = description ?~ "E.164 phone number to send the code to."

maybeUserKeyFromTuple :: (Maybe Email, Maybe Phone) -> Parser (Either Email Phone)
maybeUserKeyFromTuple = \case
(Just _, Just _) -> fail "Only one of 'email' or 'phone' allowed."
(Just email, Nothing) -> pure $ Left email
(Nothing, Just phone) -> pure $ Right phone
(Nothing, Nothing) -> fail "One of 'email' or 'phone' required."
?~ "Data for requesting an email code to be sent. 'email' must be present."
Loading