/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:
| Value | Game |
|---|---|
dinoparc.com | Dinoparc |
en.dinoparc.com | Dinoparc |
sp.dinoparc.com | Dinoparc |
hammerfest.fr | Hammerfest |
hfest.net | Hammerfest |
hammerfest.es | Hammerfest |
twinoid.com | Twinoid |
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.
:remote | Field | Type |
|---|---|---|
| a Dinoparc server | dinoparc_user_id | decimal string |
| a Hammerfest server | hammerfest_user_id | decimal string |
twinoid.com | twinoid_user_id | decimal 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
| Status | Body | When |
|---|---|---|
| 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
| Status | Body | When |
|---|---|---|
| 400 | {"error": "bad request"} | Malformed reference. |
| 500 | {"error": "internal error"} | Not the owner nor an administrator, no such link, or a store failure. |