github.com/cozy/cozy-stack@v0.0.0-20240603063001-31110fa4cae1/docs/move-design.md (about)

     1  [Table of contents](README.md#table-of-contents)
     2  
     3  # Move design
     4  
     5  > "You will stay because you can leave" - Cozy.
     6  
     7  We have made this important promise to our users, and moving a Cozy to a new
     8  hoster/address is a big part of it. That's why we have tried hard to make it
     9  smooth and robust. It means that we had to manage some complex special cases.
    10  This document is here to keep a trace of them.
    11  
    12  But, first, let's define what moving a Cozy means. When you have an instance,
    13  the "source", and another instance, the "target", the user can move their usage
    14  from the source to the target. The data is exported from the source instance,
    15  and imported on the target instance. But there is more than that. For example,
    16  the Cozy to Cozy sharings ([documentation](./sharing-design.md)) will be
    17  updated to work the target instance instead of the source instance.
    18  
    19  
    20  ## Workflows
    21  
    22  Technically, a new component called [Cozy-Move](https://github.com/cozy/cozy-move)
    23  was created. It is a web application in Elixir/Phoenix that can be seen as a
    24  wizard to help users select from which instance and to which instance they want
    25  to move. It is possible to send a mail with a link to cozy-move, and put this
    26  link in a FAQ, and users can start the process from this link. But, if a user
    27  wants to initiate a move by them-self, they will start from the settings of
    28  their Cozy. The two workflows are available.
    29  
    30  ### Starting from settings
    31  
    32  ![Starting from settings](./diagrams/from-settings.png)
    33  
    34  ### Starting from cozy-move
    35  
    36  ![Starting from cozy-move](./diagrams/from-cozy-move.png)
    37  
    38  ### Notes
    39  
    40  For security, we need an interaction of the user with both instances (even if
    41  the user is already logged). There is a confirmation mail sent by the source
    42  Cozy, that counts as a interaction. For the target Cozy, a click on a page
    43  served by the stack could have been enough, but asking the password was easier
    44  to explain to the user and improve the sense of security as perceived by the
    45  user, so that was what we did. And we had to take care of that to allow or
    46  forbid swapping instances on Cozy-Move.
    47  
    48  The token exchanges are inspired by OAuth 2.0, but don't follow OAuth 2.0 as it
    49  would have made the user experience really awkwards with lots of redirections
    50  and meaningless screens. The confirmation mail is really important, as it is
    51  a safeguard if the worflows are not as robust as we think they are.
    52  
    53  
    54  ## Source instance
    55  
    56  Exporting the data from a Cozy was a feature already implemented in the stack.
    57  The user can ask an export of their Cozy: the stack will send a mail with a
    58  link, and after following the link, the user can download the data as a zip. If
    59  the VFS ([Virtual File System](./files.md#virtual-file-system)) takes a lot of
    60  space, the zip will be split in several parts.
    61  
    62  When an export if part of a move, the instance is blocked to avoid any change
    63  that could increase the risk of inconsistencies during the move.
    64  
    65  And, if the move is successful, the OAuth clients are revoked to encourage the
    66  user to reconnect them on the target. Also, the source instance will be
    67  destroyed 30 days later. It gives time to the user to check that every thing is
    68  OK on their new instance, and can be used to alert other users that want to see
    69  a page shared by link of the new address of the sharing.
    70  
    71  ### Zip vs Tar
    72  
    73  The export produces a zip file (or several files if it is too large). But the
    74  stack first makes a tar file while preparing the export. At first, it looks
    75  strange, but we though that a zip will be more friendly for users, and a tar is
    76  more adapted to our constraints. A tar can be read sequentially while a zip
    77  needs random access, and it was easier to stream a tar from Swift and converts
    78  it to zip, than trying to add entries to a zip file (and we didn't want to copy
    79  the whole files from the VFS in the zip in Swift as it takes too much space).
    80  
    81  
    82  ## Target instance
    83  
    84  Importing a zip can also be done before moving: the user can go in the settings
    85  of their Cozy, gives the URL of the zip, and let the Cozy imports it. The Cozy
    86  is reset before the import: the data is erased!
    87  
    88  We would like to offer a way to merge the existing data and the data to import,
    89  but it looks really complex and we think that it is more useful to use our time
    90  on other features.
    91  
    92  At the end of the import, a mail is sent to the user to tell them that they can
    93  use again their Cozy (the instance is blocked during the reset+import).
    94  
    95  
    96  ## Special doctypes
    97  
    98  ### Apps
    99  
   100  The home, settings, and store applications are always installed on the target Cozy.
   101  And we also try to install all the webapps and konnectors from the source, but
   102  it can fail as they might not be available (e.g. the 2 Cozys don't have the
   103  same apps registry). In that case, the user will be alerted in the mail sent at the
   104  end of the import.
   105  
   106  For the permissions, we recreate them from the manifest and don't try to import them
   107  from the source instance.
   108  
   109  ### Email address
   110  
   111  The email address on the target instance is kept. We don't import the email
   112  address the user had on their source instance. The stack also keep other
   113  settings that are tied to the cloudery (UUID, ToS, context).
   114  
   115  We also update the myself document with the kept email address.
   116  
   117  ### Files
   118  
   119  The directories, files, and versions are imported. The thumbnails are not
   120  exported/imported, but rebuilt on the target instance.
   121  
   122  If the quota of the target is too small for the files from the source, we alert
   123  the user before the move.
   124  
   125  ### Konnectors
   126  
   127  See the apps section. For konnectors that have a on_delete_accounts hook, we have
   128  to use some tricks:
   129  
   130  - we delete the accounts on the target instance for the reset while the
   131    instance is blocked, but the konnectors can still make requests to the stack
   132    for those executions (allowed via a flag in redis)
   133  - the accounts from the source instance are not imported on the target, as they
   134    will be useless soon (when they will be deleted by the source).
   135  
   136  ### Sessions
   137  
   138  They are not imported.
   139  
   140  ### Sharings
   141  
   142  For the shared by links, we import the permission document. But the link given
   143  to other users will still go on the old instance. While this instance is not
   144  deleted, it will show a page that gives the new link.
   145  
   146  For the Cozy to Cozy sharings, the stack has a mechanism for updating them so
   147  that the other instances will now synchronize with the target. It is a bit
   148  complicated as we have to make it work if several members of a sharing has
   149  moving at the same time, and as the JWT tokens are tied to an instance and have
   150  to be renewed (access token & refresh token).
   151  
   152  ### Triggers
   153  
   154  We import the triggers for the sharings and konnectors. For the apps
   155  (services), they are recreated when installed. The trigger for the
   156  thumbnails is also recreated when the instance is reset (not imported).
   157  
   158  Note: the triggers are imported at the end to avoid creating many jobs when
   159  importing the shared files.
   160  
   161  ### Vault
   162  
   163  The bitwarden vault is encrypted with a key not available on the servers (on
   164  purpose). It makes difficult to move it automatically, but the stack can detect
   165  if the vault has been used, and in that case, show instructions to export and
   166  import the passwords.