Skip to content
Draft
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
6 changes: 3 additions & 3 deletions cabal.project
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ packages:
, services/galley/
, services/gundeck/
, services/proxy/
, services/wire-server-enterprise
-- , services/wire-server-enterprise
, services/spar/
, tools/db/assets/
, tools/db/auto-whitelist/
Expand Down Expand Up @@ -90,8 +90,8 @@ package extended
flags: +nix-dev-env
package metrics-wai
flags: +nix-dev-env
package wire-server-enterprise
flags: +nix-dev-env
-- package wire-server-enterprise
-- flags: +nix-dev-env
package spar
flags: +nix-dev-env
package wire-message-proto-lens
Expand Down
46 changes: 0 additions & 46 deletions libs/wire-api/src/Wire/API/Routes/Public/Brig.hs
Original file line number Diff line number Diff line change
Expand Up @@ -492,32 +492,6 @@ type SelfAPI =
:> ReqBody '[JSON] UserUpdate
:> MultiVerb1 'PUT '[JSON] (RespondEmpty 200 "User updated")
)
:<|> Named
"change-phone"
( Summary "Change your phone number."
:> Until 'V6
:> ZUser
:> ZConn
:> "self"
:> "phone"
:> ReqBody '[JSON] PhoneUpdate
:> MultiVerb 'PUT '[JSON] ChangePhoneResponses (Maybe ChangePhoneError)
)
:<|>
-- This endpoint can lead to the following events being sent:
-- - UserIdentityRemoved event to self
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."
:> ZUser
:> "self"
:> "phone"
:> MultiVerb 'DELETE '[JSON] RemoveIdentityResponses (Maybe RemoveIdentityError)
)
:<|>
-- This endpoint can lead to the following events being sent:
-- - UserIdentityRemoved event to self
Expand Down Expand Up @@ -1767,26 +1741,6 @@ type AuthAPI =
:> CanThrow 'BadCredentials
:> MultiVerb1 'POST '[JSON] TokenResponse
)
:<|> Named
"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.\
\ A login code can be used only once and times out after\
\ 10 minutes. Only one login code may be pending at a time.\
\ For 2nd factor authentication login with email and password, use the\
\ `/verification-code/send` endpoint."
:> ReqBody '[JSON] SendLoginCode
:> CanThrow 'InvalidPhone
:> CanThrow 'PasswordExists
:> MultiVerb1
'POST
'[JSON]
(Respond 200 "OK" LoginCodeTimeout)
)
:<|> Named
"login"
( "login"
Expand Down
35 changes: 0 additions & 35 deletions libs/wire-api/src/Wire/API/User.hs
Original file line number Diff line number Diff line change
Expand Up @@ -87,9 +87,6 @@ module Wire.API.User
ChangePasswordResponses,
LocaleUpdate (..),
EmailUpdate (..),
PhoneUpdate (..),
ChangePhoneError (..),
ChangePhoneResponses,
RemoveIdentityError (..),
RemoveIdentityResponses,
HandleUpdate (..),
Expand Down Expand Up @@ -1557,38 +1554,6 @@ instance ToByteString EmailActivation where
builder SendActivationEmail = "send_activation_email"
builder AutoActivate = "auto_activate"

newtype PhoneUpdate = PhoneUpdate {puPhone :: Phone}
deriving stock (Eq, Show, Generic)
deriving newtype (Arbitrary)
deriving (ToJSON, FromJSON, S.ToSchema) via Schema PhoneUpdate

instance ToSchema PhoneUpdate where
schema =
object "PhoneUpdate" $
PhoneUpdate
<$> puPhone
.= field "phone" schema

data ChangePhoneError
= PhoneExists
| InvalidNewPhone
deriving (Generic)
deriving (AsUnion ChangePhoneErrorResponses) via GenericAsUnion ChangePhoneErrorResponses ChangePhoneError

instance GSOP.Generic ChangePhoneError

type ChangePhoneErrorResponses =
[ ErrorResponse 'UserKeyExists,
ErrorResponse 'InvalidPhone
]

type ChangePhoneResponses =
ChangePhoneErrorResponses .++ '[RespondEmpty 202 "Phone updated"]

instance (res ~ ChangePhoneResponses) => AsUnion res (Maybe ChangePhoneError) where
toUnion = maybeToUnion (toUnion @ChangePhoneErrorResponses)
fromUnion = maybeFromUnion (fromUnion @ChangePhoneErrorResponses)

data RemoveIdentityError
= LastIdentity
| NoIdentity
Expand Down
37 changes: 1 addition & 36 deletions libs/wire-api/src/Wire/API/User/Auth.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ module Wire.API.User.Auth
LoginCode (..),
LoginId (..),
PendingLoginCode (..),
SendLoginCode (..),
LoginCodeTimeout (..),

-- * Cookies
Expand Down Expand Up @@ -86,7 +85,7 @@ import Imports
import Servant
import Web.Cookie
import Wire.API.Routes.MultiVerb
import Wire.API.User.Identity (EmailAddress, Phone)
import Wire.API.User.Identity (EmailAddress)
import Wire.Arbitrary (Arbitrary (arbitrary), GenericUniform (..))

--------------------------------------------------------------------------------
Expand Down Expand Up @@ -154,40 +153,6 @@ instance ToSchema PendingLoginCode where
<$> pendingLoginCode .= field "code" schema
<*> pendingLoginTimeout .= field "expires_in" schema

--------------------------------------------------------------------------------
-- SendLoginCode

-- | A request for sending a 'LoginCode'
data SendLoginCode = SendLoginCode
{ lcPhone :: Phone,
lcCall :: Bool,
lcForce :: Bool
}
deriving stock (Eq, Show, Generic)
deriving (Arbitrary) via (GenericUniform SendLoginCode)
deriving (FromJSON, ToJSON, S.ToSchema) via Schema SendLoginCode

instance ToSchema SendLoginCode where
schema =
objectWithDocModifier
"SendLoginCode"
(description ?~ "Payload for requesting a login code to be sent")
$ SendLoginCode
<$> lcPhone
.= fieldWithDocModifier
"phone"
(description ?~ "E.164 phone number to send the code to")
(unnamed schema)
<*> lcCall
.= fmap
(fromMaybe False)
( optFieldWithDocModifier
"voice_call"
(description ?~ "Request the code with a call instead (default is SMS)")
schema
)
<*> lcForce .= fmap (fromMaybe True) (optField "force" schema)

--------------------------------------------------------------------------------
-- LoginCodeTimeout

Expand Down
65 changes: 62 additions & 3 deletions libs/wire-api/src/Wire/API/User/Identity.hs
Original file line number Diff line number Diff line change
Expand Up @@ -47,14 +47,19 @@ module Wire.API.User.Identity
where

import Cassandra qualified as C
import Control.Applicative (optional)
import Control.Error (hush)
import Control.Lens (dimap, (.~), (?~))
import Control.Lens (dimap, over, (.~), (?~))
import Data.Aeson (FromJSON (..), ToJSON (..))
import Data.Aeson qualified as A
import Data.Aeson.Types qualified as A
import Data.Attoparsec.Text
import Data.ByteString (fromStrict, toStrict)
import Data.ByteString.Conversion
import Data.ByteString.UTF8 qualified as UTF8
import Data.OpenApi (ToParamSchema (..))
import Data.OpenApi qualified as S
import Data.Proxy (Proxy (Proxy))
import Data.Schema
import Data.Text qualified as Text
import Data.Text.Encoding
Expand All @@ -66,15 +71,69 @@ import SAML2.WebSSO.Test.Arbitrary ()
import SAML2.WebSSO.Types qualified as SAML
import SAML2.WebSSO.XML qualified as SAML
import Servant
import Servant.API qualified as S
import System.FilePath ((</>))
import Test.QuickCheck qualified as QC
import Text.Email.Parser
import URI.ByteString qualified as URI
import URI.ByteString.QQ (uri)
import Web.Scim.Schema.User.Email ()
import Wire.API.User.EmailAddress
import Wire.API.User.Phone
import Wire.API.User.Profile (fromName, mkName)
import Wire.Arbitrary (Arbitrary, GenericUniform (..))
import Wire.Arbitrary (Arbitrary (arbitrary), GenericUniform (..))

--------------------------------------------------------------------------------
-- Phone (minimal definition for backward compatibility)

-- | Phone number in E.164 format. This type is kept for backward compatibility
-- in API schemas and data structures, but phone-based functionality has been removed.
newtype Phone = Phone {fromPhone :: Text}
deriving stock (Eq, Ord, Show, Generic)
deriving (ToJSON, FromJSON, S.ToSchema) via (Schema Phone)

instance ToParamSchema Phone where
toParamSchema _ = toParamSchema (Proxy @Text)

instance ToSchema Phone where
schema =
over doc (S.description ?~ "E.164 phone number") $
fromPhone
.= parsedText "PhoneNumber" (maybe (Left "Invalid phone number. Expected E.164 format.") Right . parsePhone)

instance ToByteString Phone where
builder = builder . fromPhone

instance FromByteString Phone where
parser = parser >>= maybe (fail "Invalid phone") pure . parsePhone

instance S.FromHttpApiData Phone where
parseUrlPiece = maybe (Left "Invalid phone") Right . fromByteString . encodeUtf8

instance S.ToHttpApiData Phone where
toUrlPiece = decodeUtf8With lenientDecode . toByteString'

instance Arbitrary Phone where
arbitrary =
Phone . Text.pack <$> do
let mkdigits n = replicateM n (QC.elements ['0' .. '9'])
mini <- mkdigits 8
maxi <- mkdigits =<< QC.chooseInt (0, 7)
pure $ '+' : mini <> maxi

deriving instance C.Cql Phone

-- | Parses a phone number in E.164 format with a mandatory leading '+'.
parsePhone :: Text -> Maybe Phone
parsePhone p
| isValidPhone p = Just $! Phone p
| otherwise = Nothing

-- | Checks whether a phone number is valid, i.e. it is in E.164 format
-- with a mandatory leading '+' followed by 10-15 digits.
isValidPhone :: Text -> Bool
isValidPhone = either (const False) (const True) . parseOnly e164
where
e164 = char '+' *> count 8 digit *> count 7 (optional digit) *> endOfInput

--------------------------------------------------------------------------------
-- UserIdentity
Expand Down
2 changes: 1 addition & 1 deletion libs/wire-api/src/Wire/API/User/Password.hs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ import Data.Tuple.Extra
import Imports
import Servant (FromHttpApiData (..))
import Wire.API.User.EmailAddress
import Wire.API.User.Phone
import Wire.API.User.Identity (Phone)
import Wire.Arbitrary (Arbitrary, GenericUniform (..))

--------------------------------------------------------------------------------
Expand Down
94 changes: 0 additions & 94 deletions libs/wire-api/src/Wire/API/User/Phone.hs

This file was deleted.

Loading