پیوند دستگاه جدید
This document describes the architecture of the feature allowing users to link their account to a new device, referred to as the Link new device
process.
Terminology
To understand this document, here are some key terms:
import side
: The device importing the account.export side
: The device exporting the account.token
: A URI that identifies a device on the Distributed Hash Table (DHT).
State machine
The daemon
manages this functionality using a state machine.
The state evolution is communicated to clients, enabling the appropriate interface display.
Currently, the state machine is symmetrical for both import side
and export side
, though certain states are inaccessible depending on the side.
State overview
وضعیت |
نام |
Usage (Side) |
توضیحات |
---|---|---|---|
0 |
Init |
هیچکدام |
Initial state. |
1 |
Token available |
Import only |
The |
۲ |
در حال اتصال |
Export/Import |
A peer-to-peer connection is being established. |
۳ |
Authenticating |
Export/Import |
The identity of the account and device address are being confirmed. |
۴ |
In progress |
Export/Import |
State transition, the account archive is being transferred. |
5 |
انجام شد |
Export/Import |
Final state. Represents success or failure. |
جزییات
The state machine can include supplementary information for display purposes, passed as a map<String, String>
called details
.
Details for import side
وضعیت |
نام |
جزییات |
---|---|---|
0 |
Init |
Not applicable. |
1 |
Token available |
|
۲ |
در حال اتصال |
No details. |
۳ |
Authenticating |
|
۴ |
In progress |
No details. |
5 |
انجام شد |
|
Details for export side
وضعیت |
نام |
جزییات |
---|---|---|
0 |
Init |
Not applicable. |
1 |
Token available |
Not applicable. |
۲ |
در حال اتصال |
No details. |
۳ |
Authenticating |
|
۴ |
In progress |
No details. |
5 |
انجام شد |
|
API between daemon and client
API for import side
Signal Name |
Direction |
Purpose |
---|---|---|
|
Outbound |
Announces the intent to import an account. Must include the key |
|
Outbound |
Provides a password if needed and confirms the identity of the imported account. |
|
Outbound |
Cancels the operation. |
|
Inbound |
Indicates the new state and provides details. |
API for export side
Signal Name |
Direction |
Purpose |
---|---|---|
|
Outbound |
Announces the intent to export an account. |
|
Outbound |
Confirms the address of the exporting device. |
|
Outbound |
Cancels the operation. |
|
Inbound |
Indicates the new state and provides details. |
Daemon state machine
stateDiagram-v2
state "Import Side" as Import {
[*] --> Import_Init
Import_Init --> Import_TokenAvailable: Generate token
Import_TokenAvailable --> Import_Connecting: Peer detected
Import_Connecting --> Import_Authenticating: Connection established
Import_Authenticating --> Import_InProgress: Auth success
Import_InProgress --> Import_Done: Transfer complete
note right of Import_TokenAvailable
Provides:
- Authentication code
- QR data
end note
note right of Import_Authenticating
May require password
auth_scheme: "", "none", "password"
end note
note right of Import_Done
error: "", "none", "network", "authentication"
end note
}
state "Export Side" as Export {
[*] --> Export_Init
Export_Init --> Export_Connecting: Token validated
Export_Connecting --> Export_Authenticating: Connection established
Export_Authenticating --> Export_InProgress: Auth success
Export_InProgress --> Export_Done: Transfer complete
note right of Export_Init
Accepts:
- Authentication code
- QR data
end note
note right of Export_Authenticating
Confirms peer address
end note
}
Client state machine
stateDiagram-v2
[*] --> Initial
Initial --> ImportDevice: ImportFromDevice selected
Initial --> ExportDevice: ExportToDevice selected
state "Import Device" as ImportDevice {
[*] --> Import_Init
Import_Init --> Import_TokenAvailable: Token received
Import_TokenAvailable --> Import_Connecting: Peer detected
Import_Connecting --> Import_Authenticating: Connection established
Import_Authenticating --> Import_InProgress: Auth success
Import_InProgress --> Import_Done: Transfer complete
Import_Authenticating --> Import_Error: Bad password
Import_Connecting --> Import_Error: Connection failed
Import_InProgress --> Import_Error: Transfer failed
Import_Error --> [*]: Reset
Import_Done --> [*]: Account ready
note right of Import_TokenAvailable
Display:
- QR code
- Authentication code
- Copy button
end note
note right of Import_Authenticating
Show password input if needed
end note
}
state "Export Device" as ExportDevice {
[*] --> Export_Init
state Export_Init {
[*] --> ShowInputOptions
ShowInputOptions --> ScanQR: Camera selected
ShowInputOptions --> ManualEntry: Manual selected
ScanQR --> QRScanning: Start camera
QRScanning --> TokenObtained: QR detected
QRScanning --> ShowInputOptions: Cancel scan
ManualEntry --> TokenObtained: Valid code entered
ManualEntry --> ShowInputOptions: Cancel entry
}
Export_Init --> Export_Connecting: Token validated
Export_Connecting --> Export_Authenticating: Connection established
Export_Authenticating --> Export_InProgress: Auth provided
Export_InProgress --> Export_Done: Transfer complete
Export_Connecting --> Export_Error: Invalid token
Export_Authenticating --> Export_Error: Auth failed
Export_InProgress --> Export_Error: Transfer failed
Export_Error --> [*]: Reset
Export_Done --> [*]: Device added
note right of Export_Init
Input options:
- QR scanner
- Manual code entry
end note
note right of Export_Authenticating
Confirm peer device
end note
}
ImportDevice --> Initial: Back/Cancel
ExportDevice --> Initial: Back/Cancel
Full sequence diagram (import and export)
sequenceDiagram
box white Import Side
participant IC as New Client
participant ID as New Daemon
end
box white Export Side
participant ED as Old Daemon
participant EC as Old Client
end
%% Initial Setup
IC->>ID: addAccount(archiveURL="jami-auth")
activate ID
ID-->>IC: deviceAuthStateChanged(state=TOKEN_AVAILABLE)
Note over IC: Display QR code<br/>and auth token
%% Export Side Initiation
EC->>EC: User chooses to export
EC->>EC: Scan QR/Enter token
EC->>ED: addDevice(token)
activate ED
%% Connection Establishment
ED->>ID: DHT connection request
ID-->>IC: deviceAuthStateChanged(state=CONNECTING)
ED-->>EC: addDeviceStateChanged(state=CONNECTING)
%% Authentication Phase
ID-->>IC: deviceAuthStateChanged(state=AUTHENTICATING,<br/>peer_id, auth_scheme)
ED-->>EC: addDeviceStateChanged(state=AUTHENTICATING,<br/>peer_address)
alt Account is password protected
IC->>IC: Show password prompt
IC->>ID: provideAccountAuthentication(password)
end
EC->>ED: confirmAddDevice()
%% Transfer Phase
ID-->>IC: deviceAuthStateChanged(state=IN_PROGRESS)
ED-->>EC: addDeviceStateChanged(state=IN_PROGRESS)
ED->>ID: Transfer account archive
%% Completion
ID-->>IC: deviceAuthStateChanged(state=DONE, error="")
ED-->>EC: addDeviceStateChanged(state=DONE, error="")
deactivate ID
deactivate ED
Note over IC,EC: Account successfully linked
alt Error Scenarios
ID-->>IC: deviceAuthStateChanged(state=DONE, error="network")
ED-->>EC: addDeviceStateChanged(state=DONE, error="network")
Note over IC,EC: Network error during transfer
ID-->>IC: deviceAuthStateChanged(state=DONE, error="authentication")
ED-->>EC: addDeviceStateChanged(state=DONE, error="authentication")
Note over IC,EC: Authentication failed
end
%% Cancellation Scenarios
rect rgb(240, 240, 240)
Note over IC,EC: Optional Cancellation Flows
IC->>ID: removeAccount()
EC->>ED: cancelAddDevice()
end