Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
xx messenger iOS
Manage
Activity
Members
Labels
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Releases
Package registry
Model registry
Operate
Terraform modules
Analyze
Contributor analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
mobile
iOS
xx messenger iOS
Commits
822397ec
Commit
822397ec
authored
Aug 10, 2022
by
Bruno Muniz
Browse files
Options
Downloads
Patches
Plain Diff
Handling received requests and confirmations
parent
ef8b7555
No related branches found
No related tags found
No related merge requests found
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
Sources/OnboardingFeature/ViewModels/OnboardingUsernameViewModel.swift
+225
-114
225 additions, 114 deletions
...rdingFeature/ViewModels/OnboardingUsernameViewModel.swift
with
225 additions
and
114 deletions
Sources/OnboardingFeature/ViewModels/OnboardingUsernameViewModel.swift
+
225
−
114
View file @
822397ec
...
...
@@ -9,6 +9,8 @@ import ElixxirDAppsSDK
import
CombineSchedulers
import
DependencyInjection
import
struct
ElixxirDAppsSDK
.
FileTransfer
struct
OnboardingUsernameViewState
:
Equatable
{
var
input
:
String
=
""
var
status
:
InputField
.
ValidationStatus
=
.
unknown
(
nil
)
...
...
@@ -22,7 +24,8 @@ final class OnboardingUsernameViewModel {
@KeyObject
(
.
username
,
defaultValue
:
""
)
var
username
:
String
var
backgroundScheduler
:
AnySchedulerOf
<
DispatchQueue
>
=
DispatchQueue
.
global
()
.
eraseToAnyScheduler
()
var
backgroundScheduler
:
AnySchedulerOf
<
DispatchQueue
>
=
DispatchQueue
.
global
()
.
eraseToAnyScheduler
()
var
greenPublisher
:
AnyPublisher
<
Void
,
Never
>
{
greenRelay
.
eraseToAnyPublisher
()
}
private
let
greenRelay
=
PassthroughSubject
<
Void
,
Never
>
()
...
...
@@ -51,105 +54,114 @@ final class OnboardingUsernameViewModel {
guard
let
self
=
self
else
{
return
}
do
{
let
cMix
=
try
self
.
cMixManager
.
create
()
let
cMix
=
try
self
.
initCMix
()
try
cMix
.
startNetworkFollower
(
timeoutMS
:
10_000
)
let
e2e
=
try
self
.
initE2E
(
cMix
)
_
=
try
self
.
initUD
(
alternative
:
false
,
e2e
:
e2e
,
cMix
:
cMix
)
_
=
try
self
.
initGroupManager
(
e2e
)
_
=
try
self
.
initTransferManager
(
e2e
)
self
.
hudRelay
.
send
(
.
none
)
self
.
greenRelay
.
send
()
}
catch
{
self
.
hudRelay
.
send
(
.
none
)
self
.
stateRelay
.
value
.
status
=
.
invalid
(
error
.
localizedDescription
)
}
}
}
private
func
initCMix
()
throws
->
CMix
{
if
let
cMix
=
try
?
DependencyInjection
.
Container
.
shared
.
resolve
()
as
CMix
{
return
cMix
}
let
cMix
=
try
cMixManager
.
create
()
DependencyInjection
.
Container
.
shared
.
register
(
cMix
)
return
cMix
}
private
func
initE2E
(
_
cMix
:
CMix
)
throws
->
E2E
{
if
let
e2e
=
try
?
DependencyInjection
.
Container
.
shared
.
resolve
()
as
E2E
{
return
e2e
}
let
e2e
=
try
Login
.
live
(
cMixId
:
cMix
.
getId
(),
authCallbacks
:
.
init
(
handle
:
{
switch
$0
{
case
.
reset
(
contact
:
let
contact
,
receptionId
:
_
,
ephemeralId
:
_
,
roundId
:
_
):
break
case
.
confirm
(
contact
:
let
contact
,
receptionId
:
_
,
ephemeralId
:
_
,
roundId
:
_
):
break
case
.
request
(
contact
:
let
contact
,
receptionId
:
_
,
ephemeralId
:
_
,
roundId
:
_
):
if
let
contactId
=
try
?
self
.
getIdFromContact
(
contact
),
let
_
=
try
?
self
.
database
.
fetchContacts
(
Contact
.
Query
(
id
:
[
contactId
]))
.
first
{
return
}
let
contactId
=
try!
self
.
getIdFromContact
(
contact
)
let
facts
=
try
?
self
.
getFactsFromContact
(
contact
:
contact
)
let
username
=
facts
?
.
first
(
where
:
{
$0
.
type
==
FactType
.
username
.
rawValue
})?
.
fact
let
email
=
facts
?
.
first
(
where
:
{
$0
.
type
==
FactType
.
email
.
rawValue
})?
.
fact
let
phone
=
facts
?
.
first
(
where
:
{
$0
.
type
==
FactType
.
phone
.
rawValue
})?
.
fact
_
=
try
?
self
.
database
.
saveContact
(
.
init
(
id
:
contactId
,
marshaled
:
contact
,
username
:
username
,
email
:
email
,
phone
:
phone
,
nickname
:
nil
,
photo
:
nil
,
authStatus
:
.
verificationInProgress
,
isRecent
:
true
,
createdAt
:
Date
()
))
case
.
reset
(
contact
:
let
contact
,
receptionId
:
_
,
ephemeralId
:
_
,
roundId
:
_
):
self
.
handleReset
(
from
:
contact
)
case
.
confirm
(
contact
:
let
contact
,
receptionId
:
_
,
ephemeralId
:
_
,
roundId
:
_
):
self
.
handleConfirm
(
from
:
contact
)
case
.
request
(
contact
:
let
contact
,
receptionId
:
_
,
ephemeralId
:
_
,
roundId
:
_
):
self
.
handleRequest
(
from
:
contact
)
}
}
),
identity
:
cMix
.
makeLegacyReceptionIdentity
()
)
DependencyInjection
.
Container
.
shared
.
register
(
cMix
)
try
e2e
.
registerListener
(
senderId
:
nil
,
messageType
:
2
,
callback
:
.
init
(
handle
:
{
message
in
print
(
message
.
timestamp
)
})
)
DependencyInjection
.
Container
.
shared
.
register
(
e2e
)
return
e2e
}
private
func
initUD
(
alternative
:
Bool
,
e2e
:
E2E
,
cMix
:
CMix
)
throws
->
UserDiscovery
{
if
let
userDiscovery
=
try
?
DependencyInjection
.
Container
.
shared
.
resolve
()
as
UserDiscovery
{
return
userDiscovery
}
guard
let
certPath
=
Bundle
.
module
.
path
(
forResource
:
"cmix.rip"
,
ofType
:
"crt"
),
let
contactFilePath
=
Bundle
.
module
.
path
(
forResource
:
"udContact"
,
ofType
:
"bin"
)
else
{
fatalError
(
"Couldn't retrieve alternative UD credentials"
)
}
let
address
=
alternative
?
"46.101.98.49:18001"
:
e2e
.
getUdAddressFromNdf
()
let
cert
=
alternative
?
try
Data
(
contentsOf
:
URL
(
fileURLWithPath
:
certPath
))
:
e2e
.
getUdCertFromNdf
()
let
contactFile
=
alternative
?
try
Data
(
contentsOf
:
URL
(
fileURLWithPath
:
contactFilePath
))
:
try
e2e
.
getUdContactFromNdf
()
let
userDiscovery
=
try
NewOrLoadUd
.
live
(
.
init
(
e2eId
:
e2e
.
getId
(),
follower
:
.
init
(
handle
:
{
cMix
.
networkFollowerStatus
()
.
rawValue
}),
username
:
self
.
stateRelay
.
value
.
input
,
registrationValidationSignature
:
cMix
.
getReceptionRegistrationValidationSignature
(),
cert
:
Data
(
contentsOf
:
URL
(
fileURLWithPath
:
certPath
))
,
contactFile
:
Data
(
contentsOf
:
URL
(
fileURLWithPath
:
contactFile
Path
))
,
address
:
"46.101.98.49:18001"
cert
:
cert
,
contactFile
:
contactFile
,
address
:
address
))
self
.
username
=
self
.
stateRelay
.
value
.
input
username
=
self
.
stateRelay
.
value
.
input
DependencyInjection
.
Container
.
shared
.
register
(
userDiscovery
)
return
userDiscovery
}
try
e2e
.
registerListener
(
senderId
:
nil
,
messageType
:
2
,
callback
:
.
init
(
handle
:
{
message
in
print
(
message
.
timestamp
)
})
)
DependencyInjection
.
Container
.
shared
.
register
(
e2e
)
private
func
initGroupManager
(
_
e2e
:
E2E
)
throws
->
GroupChat
{
if
let
groupManager
=
try
?
DependencyInjection
.
Container
.
shared
.
resolve
()
as
GroupChat
{
return
groupManager
}
let
groupManager
=
try
NewGroupChat
.
live
(
e2eId
:
e2e
.
getId
(),
groupRequest
:
.
init
(
handle
:
{
print
(
$0
)
}),
groupChatProcessor
:
.
init
(
handle
:
{
print
(
$0
)
})
groupRequest
:
.
init
(
handle
:
{
print
(
$0
)
}),
groupChatProcessor
:
.
init
(
handle
:
{
print
(
$0
)
})
)
DependencyInjection
.
Container
.
shared
.
register
(
groupManager
)
return
groupManager
}
private
func
initTransferManager
(
_
e2e
:
E2E
)
throws
->
ElixxirDAppsSDK
.
FileTransfer
{
if
let
transferManager
=
try
?
DependencyInjection
.
Container
.
shared
.
resolve
()
as
FileTransfer
{
return
transferManager
}
let
transferManager
=
try
InitFileTransfer
.
live
(
e2eId
:
e2e
.
getId
(),
...
...
@@ -164,14 +176,113 @@ final class OnboardingUsernameViewModel {
)
DependencyInjection
.
Container
.
shared
.
register
(
transferManager
)
return
transferManager
}
self
.
hudRelay
.
send
(
.
none
)
self
.
greenRelay
.
send
()
private
func
handleRequest
(
from
contact
:
Data
)
{
guard
isRepeatedRequest
(
from
:
contact
)
==
false
else
{
return
}
do
{
let
facts
=
try
?
getFactsFromContact
(
contact
:
contact
)
let
model
=
try
self
.
database
.
saveContact
(
.
init
(
id
:
try
getIdFromContact
(
contact
),
marshaled
:
contact
,
username
:
facts
?
.
first
(
where
:
{
$0
.
type
==
FactType
.
username
.
rawValue
})?
.
fact
,
email
:
facts
?
.
first
(
where
:
{
$0
.
type
==
FactType
.
email
.
rawValue
})?
.
fact
,
phone
:
facts
?
.
first
(
where
:
{
$0
.
type
==
FactType
.
phone
.
rawValue
})?
.
fact
,
nickname
:
nil
,
photo
:
nil
,
authStatus
:
.
verificationInProgress
,
isRecent
:
true
,
createdAt
:
Date
()
))
if
model
.
email
==
nil
,
model
.
phone
==
nil
{
performLookup
(
on
:
model
)
}
else
{
//performSearch()
}
}
catch
{
self
.
hudRelay
.
send
(
.
none
)
self
.
stateRelay
.
value
.
status
=
.
invalid
(
error
.
localizedDescription
)
print
(
"^^^ Request processing failed:
\(
error
.
localizedDescription
)
"
)
}
}
private
func
isRepeatedRequest
(
from
contact
:
Data
)
->
Bool
{
if
let
id
=
try
?
getIdFromContact
(
contact
),
let
_
=
try
?
self
.
database
.
fetchContacts
(
Contact
.
Query
(
id
:
[
id
]))
.
first
{
return
true
}
return
false
}
private
func
performLookup
(
on
contact
:
Contact
)
{
guard
let
e2e
=
try
?
DependencyInjection
.
Container
.
shared
.
resolve
()
as
E2E
,
let
userDiscovery
=
try
?
DependencyInjection
.
Container
.
shared
.
resolve
()
as
UserDiscovery
else
{
print
(
"^^^ couldn't resolve UD/E2E to process lookup"
)
return
}
do
{
let
_
=
try
LookupUD
.
live
(
e2eId
:
e2e
.
getId
(),
udContact
:
try
userDiscovery
.
getContact
(),
lookupId
:
contact
.
id
,
callback
:
.
init
(
handle
:
{
[
weak
self
]
in
guard
let
self
=
self
else
{
return
}
switch
$0
{
case
.
success
(
let
id
):
self
.
performOwnershipVerification
(
contact
:
contact
,
idLookedUp
:
id
)
case
.
failure
(
let
error
):
print
(
"^^^ Lookup failed:
\(
error
.
localizedDescription
)
"
)
}
})
)
}
catch
{
print
(
"^^^ Error when trying to run lookup:
\(
error
.
localizedDescription
)
"
)
}
}
private
func
performOwnershipVerification
(
contact
:
Contact
,
idLookedUp
:
Data
)
{
guard
let
e2e
=
try
?
DependencyInjection
.
Container
.
shared
.
resolve
()
as
E2E
else
{
print
(
"^^^ couldn't resolve E2E to process verification"
)
return
}
do
{
let
result
=
try
e2e
.
verifyOwnership
(
receivedContact
:
contact
.
marshaled
!
,
verifiedContact
:
idLookedUp
,
e2eId
:
e2e
.
getId
()
)
if
result
==
true
{
var
contact
=
contact
contact
.
authStatus
=
.
verified
try
database
.
saveContact
(
contact
)
}
else
{
try
database
.
deleteContact
(
contact
)
}
}
catch
{
print
(
"^^^ Exception thrown at verify ownership"
)
}
}
private
func
handleConfirm
(
from
contact
:
Data
)
{
guard
let
id
=
try
?
getIdFromContact
(
contact
)
else
{
print
(
"^^^ Couldn't get id from contact. Confirmation failed"
)
return
}
if
var
model
=
try
?
database
.
fetchContacts
(
.
init
(
id
:
[
id
]))
.
first
{
model
.
authStatus
=
.
friend
_
=
try
?
database
.
saveContact
(
model
)
}
}
private
func
handleReset
(
from
contact
:
Data
)
{
// TODO
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment