Eternaltwin

Home | /api | v1 | users

/api/v1/users/:user_id/links/:remote

The link between an Eternaltwin account and a game account. Defined in crates/rest/src/users.rs.

These are the game links, the ones that appear as links on a user. Discord and GitLab use a different mechanism, served by user-links.

:remote names the game server:

ValueGame
dinoparc.comDinoparc
en.dinoparc.comDinoparc
sp.dinoparc.comDinoparc
hammerfest.frHammerfest
hfest.netHammerfest
hammerfest.esHammerfest
twinoid.comTwinoid

Both verbs answer with the versioned link for that server — the same object that sits under the matching key of the user's links — so a client can replace one entry of the profile without re-reading it:

{
  "current": {
    "link": {
      "time": "2017-05-25T23:12:50.000Z",
      "user": {
        "type": "User",
        "id": "28dbb0bf-0fdc-40fe-ae5a-dde193f9fea8",
        "display_name": {"current": {"value": "Alice"}}
      }
    },
    "unlink": null,
    "user": {
      "type": "HammerfestUser",
      "server": "hammerfest.fr",
      "id": "127",
      "username": "elseabora"
    }
  },
  "old": []
}

link says when and by whom the link was made, unlink is null for a current link, and user is the remote account. Undone links move into old with a non-null unlink; nothing is ever erased.

PUT

Links the game account to the Eternaltwin account.

Administrators only. An ordinary member links their own accounts through the website, which proves ownership of the game account first — by signing into it — and then calls the backend-for-frontend routes listed in Internal endpoints. This route asserts a link without any such proof, which is why it is reserved.

Body

The body is discriminated by a method field. One method exists today: Ref, which names the remote account by its identifier and takes ownership for granted.

:remoteFieldType
a Dinoparc serverdinoparc_user_iddecimal string
a Hammerfest serverhammerfest_user_iddecimal string
twinoid.comtwinoid_user_iddecimal string
PUT /api/v1/users/28dbb0bf-0fdc-40fe-ae5a-dde193f9fea8/links/hammerfest.fr
Content-Type: application/json
Cookie: sid=b8be19ef-2d61-44de-b7d2-9c34ccb8a763

{"method": "Ref", "hammerfest_user_id": "127"}

The remote account must already be archived: the service resolves it through the archive store, and one that was never seen cannot be linked.

Errors

StatusBodyWhen
400{"error": "bad request"}The body does not match the shape above — wrong method, missing or malformed identifier.
500{"error": "internal error"}Everything else.

The 500 is broad on purpose in the current code: the REST layer collapses every service failure into it. A caller who is not an administrator, a remote account that is not archived and a link that conflicts with another Eternaltwin account all come back as 500 rather than as 403, 404 or 409.

DELETE

Unlinks the game account.

The caller must be the owner of the Eternaltwin account or an administrator. Unlike linking, undoing a link needs no proof of ownership of the game account: giving one up is not a claim.

Body

A reference to the remote account, with the field name that server uses:

DELETE /api/v1/users/28dbb0bf-0fdc-40fe-ae5a-dde193f9fea8/links/hammerfest.fr
Content-Type: application/json
Cookie: sid=b8be19ef-2d61-44de-b7d2-9c34ccb8a763

{"type": "HammerfestUser", "server": "hammerfest.fr", "id": "127"}

The reference is the same tagged object the API serves elsewhere: type is "DinoparcUser", "HammerfestUser" or "TwinoidUser", a Dinoparc or Hammerfest reference carries server and id, and a Twinoid one carries id alone.

The answer is the versioned link again, now with current at null and the former link moved into old.

Errors

StatusBodyWhen
400{"error": "bad request"}Malformed reference.
500{"error": "internal error"}Not the owner nor an administrator, no such link, or a store failure.