0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/bg/admin/settings/api.json b/public/language/bg/admin/settings/api.json
index 18a8783df4..8a355ab75f 100644
--- a/public/language/bg/admin/settings/api.json
+++ b/public/language/bg/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Настройки",
"lead-text": "На тази страница можете да настроите достъпа до ППИ за писане в NodeBB.",
"intro": "По подразбиране ППИ за писане удостоверява потребителите чрез бисквитката им за сесията, но NodeBB поддържа и удостоверяване чрез метода „Bearer“, използвайки кодовете от тази страница.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Щракнете тук за достъп до пълната документация на ППИ",
"require-https": "Ползването на ППИ да работи само чрез HTTPS",
"require-https-caveat": "Забележка: В някои случаи, когато се ползват програми за балансиране на натоварването, е възможно заявките към NodeBB да се препращат чрез HTTP – тогава тази настройка трябва да остане изключена.",
"uid": "Потребителски ИД",
+ "token": "Token",
"uid-help-text": "Посочете потребителски ИД, който да бъде свързан с този код. Ако ИД е 0
, това ще се счита за главен код, който може да приема идентичността на всеки от другите потребители чрез параметъра _uid
",
"description": "Описание",
- "last-seen-ago": "Последно използван .",
- "last-seen-on": "Последно използван на .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "Този ключ не е използван никога.",
"no-description": "Няма описание.",
- "token-on-save": "Кодът ще бъде създаден след като данните бъдат запазени"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/bn/admin/settings/api.json b/public/language/bn/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/bn/admin/settings/api.json
+++ b/public/language/bn/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/cs/admin/settings/api.json b/public/language/cs/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/cs/admin/settings/api.json
+++ b/public/language/cs/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/da/admin/settings/api.json b/public/language/da/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/da/admin/settings/api.json
+++ b/public/language/da/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/de/admin/settings/api.json b/public/language/de/admin/settings/api.json
index 6295bfc6e4..6a78712de7 100644
--- a/public/language/de/admin/settings/api.json
+++ b/public/language/de/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Einstellungen",
"lead-text": "Auf dieser Seite kanst Du den Zugriff auf die Write-API in NodeBB konfigurieren.",
"intro": "Standardmäßig authentifiziert die Write-API Benutzer basierend auf ihrem Sitzungscookie, aber NodeBB unterstützt auch die Bearer-Authentifizierung über Token, die über diese Seite generiert werden.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Klicke hier, um auf die vollständige API-Spezifikation zuzugreifen",
"require-https": "API-Nutzung nur über HTTPS möglich",
"require-https-caveat": "Hinweis: Einige Installationen mit Load Balancern können ihre Anfragen über HTTP an NodeBB weiterleiten, in diesem Fall sollte diese Option deaktiviert bleiben.",
"uid": "Nutzer–ID",
+ "token": "Token",
"uid-help-text": "Gebe eine Benutzer-ID an, die diesem Token zugeordnet werden soll. Wenn die Benutzer-ID 0
ist, wird sie als Master-Token betrachtet, das basierend auf dem _uid
-Parameter die Identität anderer Benutzer annehmen kann",
"description": "Beschreibung",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "Keine Beschreibung angegeben.",
- "token-on-save": "Token wird generiert, sobald das Formular gespeichert wird"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/el/admin/settings/api.json b/public/language/el/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/el/admin/settings/api.json
+++ b/public/language/el/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/en-GB/admin/settings/api.json b/public/language/en-GB/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/en-GB/admin/settings/api.json
+++ b/public/language/en-GB/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/en-US/admin/settings/api.json b/public/language/en-US/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/en-US/admin/settings/api.json
+++ b/public/language/en-US/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/en-x-pirate/admin/settings/api.json b/public/language/en-x-pirate/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/en-x-pirate/admin/settings/api.json
+++ b/public/language/en-x-pirate/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/es/admin/settings/api.json b/public/language/es/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/es/admin/settings/api.json
+++ b/public/language/es/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/et/admin/settings/api.json b/public/language/et/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/et/admin/settings/api.json
+++ b/public/language/et/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/fa-IR/admin/settings/api.json b/public/language/fa-IR/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/fa-IR/admin/settings/api.json
+++ b/public/language/fa-IR/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/fi/admin/settings/api.json b/public/language/fi/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/fi/admin/settings/api.json
+++ b/public/language/fi/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/fr/admin/settings/api.json b/public/language/fr/admin/settings/api.json
index f610282361..57fa403657 100644
--- a/public/language/fr/admin/settings/api.json
+++ b/public/language/fr/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Paramètres",
"lead-text": "À partir de cette page, vous pouvez paramétrer l'accès à l'API dans NodeBB.",
"intro": "Par défaut, l'API authentifie les utilisateurs en fonction de leur cookie de session, mais NodeBB prend également en charge l'authentification du porteur via des tokens générés via cette page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Cliquez ici pour accéder à la documentation de l'API",
"require-https": "Forcer l'utilisation de l'API via HTTPS uniquement",
"require-https-caveat": "Remarque: certaines installations impliquant des load balancer peuvent transmettre leurs requêtes à NodeBB via HTTP, auquel cas cette option doit rester désactivée.",
"uid": "ID Utilisateur",
+ "token": "Token",
"uid-help-text": "Spécifiez un ID utilisateur à associer à ce token. Si l'ID utilisateur est 0, il sera considéré comme un token maître, qui peut prendre l'identité d'autres utilisateurs en fonction du paramètre _uid
",
"description": "Description",
- "last-seen-ago": "Dernière utilisation .",
- "last-seen-on": "Dernière utilisation sur .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "Cette clé n'a jamais été utilisée.",
"no-description": "Aucune description spécifiée.",
- "token-on-save": "Le token sera généré une fois le formulaire enregistré"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/gl/admin/settings/api.json b/public/language/gl/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/gl/admin/settings/api.json
+++ b/public/language/gl/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/he/admin/settings/api.json b/public/language/he/admin/settings/api.json
index f2370a6426..d5b0915ac0 100644
--- a/public/language/he/admin/settings/api.json
+++ b/public/language/he/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "הגדרות",
"lead-text": "מעמוד זה תוכלו להגדיר גישת כתיבה ל-API ב- NodeBB.",
"intro": "כברירת מחדל, ה- API של כתיבה מאמת משתמשים בהתבסס על קובץ ה-cookie של ההפעלה שלהם, אך NodeBB תומך גם באימות נושא באמצעות טוקנים (אישורי אבטחה) שנוצרו באמצעות דף זה.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "לחץ כאן כדי לגשת למפרט ה- API המלא",
"require-https": "אפשר שימוש בAPI באמצעות HTTPS בלבד",
"require-https-caveat": "הערה: התקנות מסוימות הכוללות מאזני עומסים עשויות לשלוח את הבקשות שלהם ל-NodeBB באמצעות HTTP, ובמקרה כזה אפשרות זו צריכה להישאר מושבתת.",
"uid": "ID משתמש",
+ "token": "Token",
"uid-help-text": "ציין מזהה משתמש לשיוך לטוקן זה. אם מזהה המשתמש הוא 0
, זה ייחשב כטוקןראשי, שיכול לשער את זהותם של משתמשים אחרים על בסיס פרמטר_uid
.",
"description": "תיאור",
- "last-seen-ago": "שימוש אחרון ",
- "last-seen-on": "שימוש אחרון ב",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "מעולם לא נעשה שימוש במפתח זה.",
"no-description": "לא צוין תיאור.",
- "token-on-save": "טוקן יוצר לאחר שמירת הטופס"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/hr/admin/settings/api.json b/public/language/hr/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/hr/admin/settings/api.json
+++ b/public/language/hr/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/hu/admin/settings/api.json b/public/language/hu/admin/settings/api.json
index 31ffbce5f1..b6a0faa22c 100644
--- a/public/language/hu/admin/settings/api.json
+++ b/public/language/hu/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Beállítások",
"lead-text": "Ezen az oldalon beállíthatod a NodeBB Write API-jának hozzáférését.",
"intro": "Alapértelmezetten a Write API a felhasználókat a munkamenet sütijükön keresztül authentikálja, azonban a NodeBB támogatja a Bearer authentikációt tokeneken keresztül, amiket ezen az oldalon generálhatsz.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Kattints ide a teljes API specifikáció megtekintéséhez",
"require-https": "API használat korlátozása HTTPS protokollra",
"require-https-caveat": "Megjegyzés: Némely telepítések terherléselosztás miatt a kéréseket a NodeBB felé HTTP-n keresztül továbbítják. Ilyen esetekben ezt a beállítást nem szabad bekapcsolni.",
"uid": "Felhasználó azonosító",
+ "token": "Token",
"uid-help-text": "Adj meg egy felhasználó azonosítót, hogy társítsd ehhez a tokenhez. Ha a felhasználó azonosító 0, akkor mester tokenként lesz kezelve, ami bármelyik felhasználó identitását képes felvenni a _uid
paraméter alapján",
"description": "Leírás",
- "last-seen-ago": "Utolsó látogatás .",
- "last-seen-on": "Utolsó látogatás .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "Ezt a kulcsot soha nem használták.",
"no-description": "Nincs leírás megadva.",
- "token-on-save": "A token az űrlap mentésekor generálódik"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/hy/admin/settings/api.json b/public/language/hy/admin/settings/api.json
index f5530ad449..df89a0d5ae 100644
--- a/public/language/hy/admin/settings/api.json
+++ b/public/language/hy/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Կարգավորումներ ",
"lead-text": "Այս էջից դուք կարող եք կարգավորել մուտքը դեպի «Write API» NodeBB-ում:",
"intro": " Write API-ն նույնականացնում է օգտատերերին՝ հիմնվելով նրանց նստաշրջանի cookie-ի վրա, սակայն NodeBB-ն աջակցում է նաև կրող նույնականացումը այս էջի միջոցով ստեղծվող նշանների միջոցով:",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Սեղմեք այստեղ՝ API-ի ամբողջական ճշգրտմանը մուտք գործելու համար",
"require-https": "Պահանջել API-ի օգտագործում միայն HTTPS-ի միջոցով",
"require-https-caveat": "Նշում․ որոշ տեղադրումներ, որոնք ներառում են բեռի հավասարակշռողներ, կարող են իրենց հարցումները փոխանցել NodeBB-ին՝ օգտագործելով HTTP, որի դեպքում այս տարբերակը պետք է մնա անջատված։",
"uid": "Օգտատիրոջ ID",
+ "token": "Token",
"uid-help-text": "Նշեք Օգտատիրոջ ID՝ այս նշանի հետ կապելու համար: Եթե օգտատիրոջ ID-ն 0 է, ապա այն կհամարվի հիմնական նշան, որը կարող է ենթադրել այլ օգտատերերի ինքնությունը՝ հիմնվելով _uid պարամետրի վրա:",
"description": "Նկարագրություն",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "Ոչ մի նկարագրություն նշված չէ:",
- "token-on-save": "Ձևաթուղթը կստեղծվի, երբ ձևը պահպանվի"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/id/admin/settings/api.json b/public/language/id/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/id/admin/settings/api.json
+++ b/public/language/id/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/it/admin/settings/api.json b/public/language/it/admin/settings/api.json
index fc7bf8aec7..b6c709e347 100644
--- a/public/language/it/admin/settings/api.json
+++ b/public/language/it/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Impostazioni",
"lead-text": "Da questa pagina è possibile configurare l'accesso alle API di scrittura in NodeBB.",
"intro": "Per impostazione predefinita, l'API di scrittura autentica gli utenti in base al cookie di sessione, ma NodeBB supporta anche l'autenticazione Bearer tramite token generati tramite questa pagina.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Clicca qui per accedere alle specifiche complete dell'API",
"require-https": "Richiedi utilizzo API solo tramite HTTPS",
"require-https-caveat": "Nota:Alcune installazioni che coinvolgono bilanciatori del carico possono inviare tramite proxy le loro richieste a NodeBB utilizzando HTTP, nel qual caso questa opzione dovrebbe rimanere disabilitata.",
"uid": "ID utente",
+ "token": "Token",
"uid-help-text": "Specificare un ID utente da associare a questo token. Se l'ID utente è 0
, sarà considerato un token master, che può assumere l'identità di altri utenti in base al parametro _uid
",
"description": "Descrizione",
- "last-seen-ago": "Ultimo utilizzo .",
- "last-seen-on": "Ultimo utilizzo il .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "Questa chiave non è mai stata usata.",
"no-description": "Nessuna descrizione specificata.",
- "token-on-save": "Il token sarà generato una volta salvato il modulo"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/ja/admin/settings/api.json b/public/language/ja/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/ja/admin/settings/api.json
+++ b/public/language/ja/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/ko/admin/settings/api.json b/public/language/ko/admin/settings/api.json
index af6c41071f..638f65cf25 100644
--- a/public/language/ko/admin/settings/api.json
+++ b/public/language/ko/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "설정",
"lead-text": "이 설정 화면에서 NodeBB에 Write API의 연결을 설정할 수 있습니다.",
"intro": "기본적으로 Write API는 세션 쿠키를 기반으로 사용자를 인증하지만 NodeBB는 이 페이지를 통해 생성된 토큰을 통해 Bearer 인증도 지원합니다.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "여기를 클릭해서 자세한 API 설정 방법 확인",
"require-https": "API 사용을 HTTPS 접속으로만 허용",
"require-https-caveat": "참고: Load balancer와 관련된 일부 설치에서는 HTTP를 사용하여 요청을 NodeBB에 프록시하므로 이 옵션을 사용하지 않도록 설정해야 합니다.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "이 토큰과 연결할 User ID를 지정하세요. User ID가 0
일 경우 master 토큰으로 간주되어 다른 사용자의 정보를 _uid
패러미터를 통해 알 수 있게 됩니다.",
"description": "설명",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "설명 없음",
- "token-on-save": "현재 설정 저장 후 토큰 생성"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/lt/admin/settings/api.json b/public/language/lt/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/lt/admin/settings/api.json
+++ b/public/language/lt/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/lv/admin/settings/api.json b/public/language/lv/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/lv/admin/settings/api.json
+++ b/public/language/lv/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/ms/admin/settings/api.json b/public/language/ms/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/ms/admin/settings/api.json
+++ b/public/language/ms/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/nb/admin/settings/api.json b/public/language/nb/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/nb/admin/settings/api.json
+++ b/public/language/nb/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/nl/admin/settings/api.json b/public/language/nl/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/nl/admin/settings/api.json
+++ b/public/language/nl/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/pl/admin/settings/api.json b/public/language/pl/admin/settings/api.json
index 55ece93210..0a7ca7a928 100644
--- a/public/language/pl/admin/settings/api.json
+++ b/public/language/pl/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Ustawienia",
"lead-text": "Na tej stronie możesz skonfigurować dostęp do Write API w NodeBB.",
"intro": "Domyślnie Write API uwierzytelnia użytkowników na podstawie ich sesji cookie, ale NodeBB obsługuje również uwierzytelnianie okaziciela za pomocą tokenów generowanych za pośrednictwem tej strony.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Kliknij tutaj, aby zobaczyć pełną specyfikację API",
"require-https": "Wymagaj użycia API tylko przez HTTPS",
"require-https-caveat": "Notatka: Niektóre instalacje z modułami równoważenia obciążenia mogą przekazywać swoje żądania do NodeBB za pomocą protokołu HTTP, w takim przypadku ta opcja powinna pozostać wyłączona.",
"uid": "ID Użytkownika",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Opis",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "Brak opisu.",
- "token-on-save": "Token zostanie wygenerowany po zapisaniu formularza"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/pt-BR/admin/settings/api.json b/public/language/pt-BR/admin/settings/api.json
index d363fcb163..0bc1ff0abe 100644
--- a/public/language/pt-BR/admin/settings/api.json
+++ b/public/language/pt-BR/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Configurações",
"lead-text": "Nesta página, você pode configurar o acesso à API de Escrita no NodeBB.",
"intro": "Por padrão, a API de Escrita autentica os usuários com base em seu cookie de \nsessão, mas o NodeBB também oferece suporte à autenticação Bearer por\n meio de tokens gerados por meio desta página.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Clique aqui para acessar a especificação completa da API",
"require-https": "Exigir uso da API apenas via HTTPS",
"require-https-caveat": "Nota: Algumas instalações que envolvem balanceadores de carga podem fazer proxy de suas solicitações para NodeBB usando HTTP, caso em que esta opção deve permanecer desabilitada.",
"uid": "ID do Usuário",
+ "token": "Token",
"uid-help-text": "Especifique um ID de usuário para associar a este token. Se o ID do usuário for0
, ele será considerada uma token master, que pode assumir a identidade de outros usuários com base no parâmetro _uid
",
"description": "Descrição",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "Nenhuma descrição especificada.",
- "token-on-save": "O token será gerado assim que o formulário for salvo"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/pt-PT/admin/settings/api.json b/public/language/pt-PT/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/pt-PT/admin/settings/api.json
+++ b/public/language/pt-PT/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/ro/admin/settings/api.json b/public/language/ro/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/ro/admin/settings/api.json
+++ b/public/language/ro/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/ru/admin/settings/api.json b/public/language/ru/admin/settings/api.json
index df16296e7d..512748e33a 100644
--- a/public/language/ru/admin/settings/api.json
+++ b/public/language/ru/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Настройки",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "ID пользователя",
+ "token": "Token",
"uid-help-text": "Укажите идентификатор пользователя, который нужно связать с этим токеном. Если идентификатор пользователя равен 0
, он будет считаться главным токеном, который может предполагать идентичность других пользователей на основе параметра _uid
.",
"description": "Описание",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "Описания нет.",
- "token-on-save": "Токен будет сгенерирован после сохранения формы"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/rw/admin/settings/api.json b/public/language/rw/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/rw/admin/settings/api.json
+++ b/public/language/rw/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/sc/admin/settings/api.json b/public/language/sc/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/sc/admin/settings/api.json
+++ b/public/language/sc/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/sk/admin/settings/api.json b/public/language/sk/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/sk/admin/settings/api.json
+++ b/public/language/sk/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/sl/admin/settings/api.json b/public/language/sl/admin/settings/api.json
index 8522eb92aa..a5ae0a69df 100644
--- a/public/language/sl/admin/settings/api.json
+++ b/public/language/sl/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Nastavitve",
"lead-text": "Na tej strani lahko konfigurirate dostop do API-ja za pisanje v NodeBB.",
"intro": "API za pisanje privzeto preverja uporabnike na podlagi njihovega piškotka seje, vendar NodeBB podpira tudi preverjanje pristnosti nosilca prek žetonov, ustvarjenih na tej strani.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Kliknite tukaj za dostop do celotne specifikacije API-ja",
"require-https": "Zahtevaj uporabo API samo prek protokola HTTPS",
"require-https-caveat": "Opomba: Nekatere namestitve, ki vključujejo izravnalnike obremenitve, lahko svoje zahteve posredujejo NodeBB prek protokola HTTP, v tem primeru bi morala ta možnost ostati onemogočena.",
"uid": "ID uporabnika",
+ "token": "Token",
"uid-help-text": "Določite ID uporabnika, ki ga želite povezati s tem žetonom. Če je ID uporabnika 0
, bo veljal za glavni žeton, ki lahko prevzame identiteto drugih uporabnikov na podlagi parametra _uid
",
"description": "Opis",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "Opis ni naveden.",
- "token-on-save": "Žeton bo ustvarjen, ko bo obrazec shranjen"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/sq-AL/admin/settings/api.json b/public/language/sq-AL/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/sq-AL/admin/settings/api.json
+++ b/public/language/sq-AL/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/sr/admin/settings/api.json b/public/language/sr/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/sr/admin/settings/api.json
+++ b/public/language/sr/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/sv/admin/settings/api.json b/public/language/sv/admin/settings/api.json
index 9bc499e3f9..f6731ef2a8 100644
--- a/public/language/sv/admin/settings/api.json
+++ b/public/language/sv/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Inställningar",
"lead-text": "Från den här sidan kan du konfigurera åtkomst till NodeBBs 'Write API'.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Tillåt endast API-användning via HTTPS",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Beskrivning",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "Ingen beskrivning finns.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/th/admin/settings/api.json b/public/language/th/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/th/admin/settings/api.json
+++ b/public/language/th/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/tr/admin/settings/api.json b/public/language/tr/admin/settings/api.json
index b40ffefcb0..c3a689b626 100644
--- a/public/language/tr/admin/settings/api.json
+++ b/public/language/tr/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Ayarlar",
"lead-text": "Bu sayfadan NodeBB'deki \"Write API\"e erişimi yapılandırabilirsiniz.",
"intro": "Varsayılan olarak, Yazma API'si kullanıcıların kimliklerini oturum tanımlama bilgileri temelinde doğrular, ancak NodeBB ayrıca bu sayfa aracılığıyla oluşturulan belirteçler aracılığıyla Taşıyıcı kimlik doğrulamasını da destekler.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Tüm API özeliklerine erişmek için buraya tıklayın. ",
"require-https": "API kullanımı için HTTPS kısıtlaması gerektir",
"require-https-caveat": "Not: Yük dengeleyicilerini içeren bazı kurulumlar, isteklerini HTTP kullanarak NodeBB'ye proxy uygulayabilir, bu durumda bu seçenek devre dışı kalmalıdır.",
"uid": "Kullanıcı ID",
+ "token": "Token",
"uid-help-text": "Bu jetonla ilişkilendirilecek bir Kullanıcı Kimliği belirtin. Kullanıcı kimliği 0 ise, diğer kullanıcıların kimliğini _uid parametresine göre üstlenebilen bir ana simge olarak kabul edilir.",
"description": "Açıklama",
- "last-seen-ago": "En son kullanıldı.",
- "last-seen-on": "En son tarihinde kullanıldı.",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "Bu anahtar daha önce hiç kullanılmadı.",
"no-description": "Hiçbir açıklama belirtilmemiş.",
- "token-on-save": "Form kaydedildikten sonra bir jeton oluşturulacak"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/uk/admin/settings/api.json b/public/language/uk/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/uk/admin/settings/api.json
+++ b/public/language/uk/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/vi/admin/settings/api.json b/public/language/vi/admin/settings/api.json
index 0b16c3af71..e511e951a1 100644
--- a/public/language/vi/admin/settings/api.json
+++ b/public/language/vi/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Cài đặt",
"lead-text": "Từ trang này, bạn có thể cấu hình quyền truy cập vào API Viết trong NodeBB.",
"intro": "Mặc định, API Viết xác thực người dùng dựa trên cookie phiên của họ, nhưng NodeBB cũng hỗ trợ xác thực Bearer thông qua mã truy cập được tạo qua trang này.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Nhấp vào đây để truy cập thông số kỹ thuật API đầy đủ",
"require-https": "Chỉ yêu cầu sử dụng API qua HTTPS",
"require-https-caveat": "Ghi chú: Một số cài đặt liên quan đến bộ cân bằng tải có thể ủy quyền các yêu cầu của họ tới NodeBB bằng HTTP, trong trường hợp đó tùy chọn này vẫn bị vô hiệu hóa.",
"uid": "ID Người Dùng",
+ "token": "Token",
"uid-help-text": "Ghi rõ ID người dùng liên kết với mã truy cập. Nếu ID người dùng là 0
, nó sẽ là môt mã truy cập cao cấp, có thể giả định danh tính của những người dùng khác dựa trên tham số _uid
",
"description": "Mô tả",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "Khóa này chưa bao giờ được dùng.",
"no-description": "Không có mô tả cụ thể.",
- "token-on-save": "Mã truy cập sẽ được tạo sau khi biểu mẫu được lưu"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/zh-CN/admin/settings/api.json b/public/language/zh-CN/admin/settings/api.json
index 8458b5afad..6ef7743074 100644
--- a/public/language/zh-CN/admin/settings/api.json
+++ b/public/language/zh-CN/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "设置",
"lead-text": "从此处,您可以配置对 NodeBB 中 Write API 的访问。",
"intro": "默认情况下,Write API 根据用户的会话cookie对用户进行身份验证,但 NodeBB 也支持通过此页面生成的令牌进行身份验证。",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "单击此处访问完整的 API 规范",
"require-https": "要求 API 只能通过 HTTPS 调用",
"require-https-caveat": "注意:一些负载均衡器可能会使用 HTTP 代理对 NodeBB 的请求,在此情况下此选项应保持关闭状态。",
"uid": "用户ID",
+ "token": "Token",
"uid-help-text": "指定要与此令牌关联的用户ID。如果用户ID是 0
, 它将被实危 最高 令牌,可以通过 _uid
参数假定其他用户的身份",
"description": "说明",
- "last-seen-ago": "最后一次使用",
- "last-seen-on": "最后一次使用于",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "从未被使用过的键值",
"no-description": "未指定说明。",
- "token-on-save": "保存表单后将生成令牌"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/language/zh-TW/admin/settings/api.json b/public/language/zh-TW/admin/settings/api.json
index 746b99068b..6fe1c23cc9 100644
--- a/public/language/zh-TW/admin/settings/api.json
+++ b/public/language/zh-TW/admin/settings/api.json
@@ -3,17 +3,25 @@
"settings": "Settings",
"lead-text": "From this page you can configure access to the Write API in NodeBB.",
"intro": "By default, the Write API authenticates users based on their session cookie, but NodeBB also supports Bearer authentication via tokens generated via this page.",
+ "warning": "Be advised — treat tokens like passwords. If they are leaked, your account should be considered compromised.",
"docs": "Click here to access the full API specification",
"require-https": "Require API usage via HTTPS only",
"require-https-caveat": "Note: Some installations involving load balancers may proxy their requests to NodeBB using HTTP, in which case this option should remain disabled.",
"uid": "User ID",
+ "token": "Token",
"uid-help-text": "Specify a User ID to associate with this token. If the user ID is 0
, it will be considered a master token, which can assume the identity of other users based on the _uid
parameter",
"description": "Description",
- "last-seen-ago": "Last used .",
- "last-seen-on": "Last used on .",
+ "last-seen": "Last seen",
+ "created": "Created",
+ "create-token": "Create Token",
+ "update-token": "Update Token",
+ "master-token": "Master token",
"last-seen-never": "This key has never been used.",
"no-description": "No description specified.",
- "token-on-save": "Token will be generated once form is saved"
+ "actions": "Actions",
+
+ "delete-confirm": "Are you sure you wish to delete this token? It will not be recoverable.",
+ "roll-confirm": "Are you sure you wish to regenerate this token? The old token will be immediately revoked and will not be recoverable."
}
\ No newline at end of file
diff --git a/public/openapi/components/schemas/admin/tokenObject.yaml b/public/openapi/components/schemas/admin/tokenObject.yaml
new file mode 100644
index 0000000000..fab6c269c4
--- /dev/null
+++ b/public/openapi/components/schemas/admin/tokenObject.yaml
@@ -0,0 +1,24 @@
+TokenObject:
+ type: object
+ properties:
+ uid:
+ type: number
+ description: A valid user id
+ description:
+ type: string
+ description: Optional descriptor to differentiate tokens.
+ token:
+ type: string
+ description: An API token that can be called against this API via Bearer Authentication.
+ timestamp:
+ type: number
+ timestampISO:
+ type: string
+ description: An ISO 8601 formatted date string (complementing `timestamp`)
+ lastSeen:
+ type: number
+ nullable: true
+ lastSeenISO:
+ type: string
+ description: An ISO 8601 formatted date string (complementing `lastSeen`)
+ nullable: true
\ No newline at end of file
diff --git a/public/openapi/read/admin/settings/api.yaml b/public/openapi/read/admin/settings/api.yaml
index c36f11d9a6..1e955d32c8 100644
--- a/public/openapi/read/admin/settings/api.yaml
+++ b/public/openapi/read/admin/settings/api.yaml
@@ -11,14 +11,8 @@ get:
allOf:
- type: object
properties:
- lastSeen:
- type: object
- description: A key-value set of API tokens and a UNIX timestamp of when it was last used
- properties: {}
- additionalProperties: {}
- lastSeenISO:
- type: object
- description: A key-value set of API tokens and an ISO 8601 formatted date string of when it was last used
- properties: {}
- additionalProperties: {}
+ tokens:
+ type: array
+ items:
+ $ref: ../../../components/schemas/admin/tokenObject.yaml#/TokenObject
- $ref: ../../../components/schemas/CommonProps.yaml#/CommonProps
\ No newline at end of file
diff --git a/public/openapi/write.yaml b/public/openapi/write.yaml
index efc9c2bc46..101da200d1 100644
--- a/public/openapi/write.yaml
+++ b/public/openapi/write.yaml
@@ -198,6 +198,12 @@ paths:
$ref: 'write/admin/analytics.yaml'
/admin/analytics/{set}:
$ref: 'write/admin/analytics/set.yaml'
+ /admin/tokens:
+ $ref: 'write/admin/tokens.yaml'
+ /admin/tokens/{token}:
+ $ref: 'write/admin/tokens/token.yaml'
+ /admin/tokens/{token}/roll:
+ $ref: 'write/admin/tokens/token/roll.yaml'
/files/:
$ref: 'write/files.yaml'
/files/folder:
diff --git a/public/openapi/write/admin/tokens.yaml b/public/openapi/write/admin/tokens.yaml
new file mode 100644
index 0000000000..c5d9cb46df
--- /dev/null
+++ b/public/openapi/write/admin/tokens.yaml
@@ -0,0 +1,32 @@
+post:
+ tags:
+ - admin
+ summary: create token
+ description: This operation creates a new API token for access to the Read and Write APIs.
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ uid:
+ type: number
+ description: The generated token will make calls against NodeBB as this user.
+ example: 1
+ description:
+ type: string
+ description: Optional descriptor to differentiate tokens.
+ example: 'My new token.'
+ responses:
+ '200':
+ description: token successfully created
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ $ref: ../../components/schemas/Status.yaml#/Status
+ response:
+ $ref: ../../components/schemas/admin/tokenObject.yaml#/TokenObject
diff --git a/public/openapi/write/admin/tokens/token.yaml b/public/openapi/write/admin/tokens/token.yaml
new file mode 100644
index 0000000000..99f6718d93
--- /dev/null
+++ b/public/openapi/write/admin/tokens/token.yaml
@@ -0,0 +1,89 @@
+get:
+ tags:
+ - admin
+ summary: get token
+ description: This operation retrieves an API token and its associated metadata
+ parameters:
+ - in: path
+ name: token
+ schema:
+ type: string
+ required: true
+ description: a valid API token
+ example: 4eb506f8-a173-4693-a41b-e23604bc973a
+ responses:
+ '200':
+ description: token successfully retrieved
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ $ref: ../../../components/schemas/Status.yaml#/Status
+ response:
+ $ref: ../../../components/schemas/admin/tokenObject.yaml#/TokenObject
+put:
+ tags:
+ - admin
+ summary: update token
+ description: This operation updates a token's metadata.
+ parameters:
+ - in: path
+ name: token
+ schema:
+ type: string
+ required: true
+ description: a valid API token
+ example: 4eb506f8-a173-4693-a41b-e23604bc973a
+ requestBody:
+ required: true
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ uid:
+ type: number
+ description: The generated token will make calls against NodeBB as this user.
+ example: 1
+ description:
+ type: string
+ description: Optional descriptor to differentiate tokens.
+ example: 'My new token.'
+ responses:
+ '200':
+ description: Token metadata updated.
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ $ref: ../../../components/schemas/Status.yaml#/Status
+ response:
+ $ref: ../../../components/schemas/admin/tokenObject.yaml#/TokenObject
+delete:
+ tags:
+ - admin
+ summary: revoke token
+ description: This operation revokes a token and removes it from the database
+ parameters:
+ - in: path
+ name: token
+ schema:
+ type: string
+ required: true
+ description: a valid API token
+ example: 4eb506f8-a173-4693-a41b-e23604bc973a
+ responses:
+ '200':
+ description: Token metadata updated.
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ $ref: ../../../components/schemas/Status.yaml#/Status
+ response: {}
\ No newline at end of file
diff --git a/public/openapi/write/admin/tokens/token/roll.yaml b/public/openapi/write/admin/tokens/token/roll.yaml
new file mode 100644
index 0000000000..f0bc7ae4f2
--- /dev/null
+++ b/public/openapi/write/admin/tokens/token/roll.yaml
@@ -0,0 +1,25 @@
+post:
+ tags:
+ - admin
+ summary: regenerate token
+ description: This operation regenerates an existing token. The previous token is immediately invalidated.
+ parameters:
+ - in: path
+ name: token
+ schema:
+ type: string
+ required: true
+ description: a valid API token
+ example: 4eb506f8-a173-4693-a41b-e23604bc973a
+ responses:
+ '200':
+ description: Token regenerated.
+ content:
+ application/json:
+ schema:
+ type: object
+ properties:
+ status:
+ $ref: ../../../../components/schemas/Status.yaml#/Status
+ response:
+ $ref: ../../../../components/schemas/admin/tokenObject.yaml#/TokenObject
\ No newline at end of file
diff --git a/public/scss/admin/admin.scss b/public/scss/admin/admin.scss
index c244fe3498..1be7f930f5 100644
--- a/public/scss/admin/admin.scss
+++ b/public/scss/admin/admin.scss
@@ -9,6 +9,7 @@
@import "./manage/privileges";
@import "./manage/tags";
@import "./manage/groups";
+@import "./settings/api";
@import "./appearance/customise";
@import "./extend/plugins";
@import "./extend/rewards";
diff --git a/public/scss/admin/settings/api.scss b/public/scss/admin/settings/api.scss
new file mode 100644
index 0000000000..41c8e61f92
--- /dev/null
+++ b/public/scss/admin/settings/api.scss
@@ -0,0 +1,7 @@
+.template-admin-settings-api {
+ [data-action="copy"]:active {
+ i::before {
+ content: '\f00c';
+ }
+ }
+}
\ No newline at end of file
diff --git a/public/src/admin/settings/api.js b/public/src/admin/settings/api.js
index ba3667e40e..4420e9a300 100644
--- a/public/src/admin/settings/api.js
+++ b/public/src/admin/settings/api.js
@@ -1,52 +1,180 @@
'use strict';
-define('admin/settings/api', ['settings', 'alerts', 'hooks'], function (settings, alerts, hooks) {
+define('admin/settings/api', ['settings', 'clipboard', 'bootbox', 'benchpress', 'api', 'alerts'], function (settings, clipboard, bootbox, Benchpress, api, alerts) {
const ACP = {};
ACP.init = function () {
settings.load('core.api', $('.core-api-settings'));
- $('#save').on('click', saveSettings);
+ $('#save').on('click', () => {
+ settings.save('core.api', $('.core-api-settings'));
+ });
+
+ // Click to copy
+ const copyEls = document.querySelectorAll('[data-component="acp/tokens"] [data-action="copy"]');
+ new clipboard(copyEls);
+
+ handleActions();
+ };
+
+ function handleActions() {
+ const formEl = document.querySelector('#content form');
+ if (!formEl) {
+ return;
+ }
+
+ formEl.addEventListener('click', (e) => {
+ const subselector = e.target.closest('[data-action]');
+ if (subselector) {
+ const action = subselector.getAttribute('data-action');
+
+ switch (action) {
+ case 'create':
+ handleTokenCreation();
+ break;
+
+ case 'edit':
+ handleTokenUpdate(subselector);
+ break;
+
+ case 'delete':
+ handleTokenDeletion(subselector);
+ break;
- hooks.on('filter:settings.sorted-list.loadItem', ({ item }) => {
- if (!ajaxify.data.lastSeen[item.token]) {
- item.lastSeen = '[[admin/settings/api:last-seen-never]]';
- return { item };
+ case 'roll':
+ handleTokenRolling(subselector);
+ break;
+ }
}
+ });
+ }
+
+ async function handleTokenCreation() {
+ const html = await Benchpress.render('admin/partials/edit-token-modal', {});
+ const parseForm = async function () {
+ const modal = this;
+ const formEl = this.get(0).querySelector('form');
+ const tokensTableBody = document.querySelector('[data-component="acp/tokens"] tbody');
+ const valid = formEl.reportValidity();
+ if (formEl && valid) {
+ const formData = new FormData(formEl);
+ const uid = formData.get('uid');
+ const description = formData.get('description');
- const cutoffMs = 1000 * 60 * 60 * 24 * Math.max(0, parseInt(config.timeagoCutoff, 10));
- let translationSuffix = 'ago';
- if (cutoffMs > 0 && Date.now() - ajaxify.data.lastSeen[item.token] > cutoffMs) {
- translationSuffix = 'on';
+ try {
+ const tokenObj = await api.post('/admin/tokens', { uid, description });
+ if (!tokensTableBody) {
+ modal.modal('hide');
+ return ajaxify.refresh();
+ }
+
+ ajaxify.data.tokens.push(tokenObj);
+ const rowEl = (await app.parseAndTranslate(ajaxify.data.template.name, 'tokens', {
+ tokens: [tokenObj],
+ })).get(0);
+
+ tokensTableBody.append(rowEl);
+ $(rowEl).find('.timeago').timeago();
+ modal.modal('hide');
+ } catch (e) {
+ alerts.error(e);
+ }
}
- item.lastSeen = `[[admin/settings/api:last-seen-${translationSuffix}, ${ajaxify.data.lastSeenISO[item.token]}]]`;
- return { item };
+ return false;
+ };
+
+ bootbox.dialog({
+ title: '[[admin/settings/api:create-token]]',
+ message: html,
+ buttons: {
+ submit: {
+ label: '[[modules:bootbox.submit]]',
+ className: 'btn-primary',
+ callback: parseForm,
+ },
+ },
});
+ }
+
+ async function handleTokenUpdate(el) {
+ const rowEl = el.closest('[data-token]');
+ const token = rowEl.getAttribute('data-token');
+ const { uid, description } = await api.get(`/admin/tokens/${token}`);
+ const parseForm = async function () {
+ const modal = this;
+ const formEl = this.get(0).querySelector('form');
+ const valid = formEl.reportValidity();
+ if (formEl && valid) {
+ const formData = new FormData(formEl);
+ const uid = formData.get('uid');
+ const description = formData.get('description');
+
+ try {
+ const tokenObj = await api.put(`/admin/tokens/${token}`, { uid, description });
+ const newEl = (await app.parseAndTranslate(ajaxify.data.template.name, 'tokens', {
+ tokens: [tokenObj],
+ })).get(0);
- hooks.on('action:settings.sorted-list.loaded', ({ listEl }) => {
- $(listEl).find('.timeago').timeago();
+ rowEl.replaceWith(newEl);
+ $(newEl).find('.timeago').timeago();
+ modal.modal('hide');
+ } catch (e) {
+ alerts.error(e);
+ }
+ }
+
+ return false;
+ };
+
+ const html = await Benchpress.render('admin/partials/edit-token-modal', { uid, description });
+ bootbox.dialog({
+ title: '[[admin/settings/api:update-token]]',
+ message: html,
+ buttons: {
+ submit: {
+ label: '[[modules:bootbox.submit]]',
+ className: 'btn-primary',
+ callback: parseForm,
+ },
+ },
});
+ }
+
+ async function handleTokenDeletion(el) {
+ const rowEl = el.closest('[data-token]');
+ const token = rowEl.getAttribute('data-token');
- hooks.on('action:settings.sorted-list.itemLoaded', ({ element }) => {
- element.addEventListener('click', (ev) => {
- if (ev.target.closest('input[readonly]')) {
- // Select entire input text
- ev.target.selectionStart = 0;
- ev.target.selectionEnd = ev.target.value.length;
+ bootbox.confirm('[[admin/settings/api:delete-confirm]]', async (ok) => {
+ if (ok) {
+ try {
+ await api.del(`/admin/tokens/${token}`);
+ } catch (e) {
+ alerts.error(e);
}
- });
+
+ rowEl.remove();
+ }
});
- };
+ }
- function saveSettings() {
- settings.save('core.api', $('.core-api-settings'), function () {
- alerts.alert({
- type: 'success',
- alert_id: 'core.api-saved',
- title: 'Settings Saved',
- timeout: 5000,
- });
- ajaxify.refresh();
+ async function handleTokenRolling(el) {
+ const rowEl = el.closest('[data-token]');
+ const token = rowEl.getAttribute('data-token');
+
+ bootbox.confirm('[[admin/settings/api:roll-confirm]]', async (ok) => {
+ if (ok) {
+ try {
+ const tokenObj = await api.post(`/admin/tokens/${token}/roll`);
+ const newEl = (await app.parseAndTranslate(ajaxify.data.template.name, 'tokens', {
+ tokens: [tokenObj],
+ })).get(0);
+
+ rowEl.replaceWith(newEl);
+ $(newEl).find('.timeago').timeago();
+ } catch (e) {
+ alerts.error(e);
+ }
+ }
});
}
diff --git a/src/api/users.js b/src/api/users.js
index 9b37d84c2f..84fe4b2b3b 100644
--- a/src/api/users.js
+++ b/src/api/users.js
@@ -18,7 +18,8 @@ const plugins = require('../plugins');
const events = require('../events');
const translator = require('../translator');
const sockets = require('../socket.io');
-const utils = require('../utils');
+
+// const api = require('.');
const usersAPI = module.exports;
@@ -308,41 +309,25 @@ usersAPI.unmute = async function (caller, data) {
};
usersAPI.generateToken = async (caller, { uid, description }) => {
+ const api = require('.');
await hasAdminPrivilege(caller.uid, 'settings');
if (parseInt(uid, 10) !== parseInt(caller.uid, 10)) {
throw new Error('[[error:invalid-uid]]');
}
- const settings = await meta.settings.get('core.api');
- settings.tokens = settings.tokens || [];
-
- const newToken = {
- token: utils.generateUUID(),
- uid: caller.uid,
- description: description || '',
- timestamp: Date.now(),
- };
- settings.tokens.push(newToken);
- await meta.settings.set('core.api', settings);
-
- return newToken;
+ const tokenObj = await api.utils.tokens.generate({ uid, description });
+ return tokenObj.token;
};
usersAPI.deleteToken = async (caller, { uid, token }) => {
+ const api = require('.');
await hasAdminPrivilege(caller.uid, 'settings');
if (parseInt(uid, 10) !== parseInt(caller.uid, 10)) {
throw new Error('[[error:invalid-uid]]');
}
- const settings = await meta.settings.get('core.api');
- const beforeLen = settings.tokens.length;
- settings.tokens = settings.tokens.filter(tokenObj => tokenObj.token !== token);
- if (beforeLen !== settings.tokens.length) {
- await meta.settings.set('core.api', settings);
- return true;
- }
-
- return false;
+ await api.utils.tokens.delete(token);
+ return true;
};
const getSessionAsync = util.promisify((sid, callback) => {
diff --git a/src/api/utils.js b/src/api/utils.js
index 63d5473e12..73f8bb67b4 100644
--- a/src/api/utils.js
+++ b/src/api/utils.js
@@ -2,12 +2,123 @@
const db = require('../database');
+const user = require('../user');
+const srcUtils = require('../utils');
+
const utils = module.exports;
// internal token management utilities only
+utils.tokens = {};
+
+utils.tokens.list = async () => {
+ // Validation handled at higher level
+ const tokens = await db.getSortedSetRange(`tokens:createtime`, 0, -1);
+ return await utils.tokens.get(tokens);
+};
+
+utils.tokens.get = async (tokens) => {
+ // Validation handled at higher level
+ if (!tokens) {
+ throw new Error('[[error:invalid-data]]');
+ }
+
+ let singular = false;
+ if (!Array.isArray(tokens)) {
+ tokens = [tokens];
+ singular = true;
+ }
+
+ let [tokenObjs, lastSeen] = await Promise.all([
+ db.getObjects(tokens.map(t => `token:${t}`)),
+ utils.tokens.getLastSeen(tokens),
+ ]);
+
+ tokenObjs = tokenObjs.map((tokenObj, idx) => {
+ if (!tokenObj) {
+ return null;
+ }
+
+ tokenObj.token = tokens[idx];
+ tokenObj.lastSeen = lastSeen[idx];
+ tokenObj.lastSeenISO = lastSeen[idx] ? new Date(lastSeen[idx]).toISOString() : null;
+ tokenObj.timestampISO = new Date(parseInt(tokenObj.timestamp, 10)).toISOString();
+
+ return tokenObj;
+ });
+
+ return singular ? tokenObjs[0] : tokenObjs;
+};
+
+utils.tokens.generate = async ({ uid, description }) => {
+ if (parseInt(uid, 10) !== 0) {
+ const uidExists = await user.exists(uid);
+ if (!uidExists) {
+ throw new Error('[[error:no-user]]');
+ }
+ }
+
+ const token = srcUtils.generateUUID();
+ const timestamp = Date.now();
+
+ return utils.tokens.add({ token, uid, description, timestamp });
+};
+
+utils.tokens.add = async ({ token, uid, description = '', timestamp = Date.now() }) => {
+ if (!token || uid === undefined) {
+ throw new Error('[[error:invalid-data]]');
+ }
+
+ await Promise.all([
+ db.setObject(`token:${token}`, { uid, description, timestamp }),
+ db.sortedSetAdd(`tokens:createtime`, timestamp, token),
+ db.sortedSetAdd(`tokens:uid`, uid, token),
+ ]);
+
+ return token;
+};
+
+utils.tokens.update = async (token, { uid, description }) => {
+ await Promise.all([
+ db.setObject(`token:${token}`, { uid, description }),
+ db.sortedSetAdd(`tokens:uid`, uid, token),
+ ]);
+
+ return await utils.tokens.get(token);
+};
+
+utils.tokens.roll = async (token) => {
+ const [createTime, uid, lastSeen] = await db.sortedSetsScore([`tokens:createtime`, `tokens:uid`, `tokens:lastSeen`], token);
+ const newToken = srcUtils.generateUUID();
+
+ const updates = [
+ db.rename(`token:${token}`, `token:${newToken}`),
+ db.sortedSetRemove(`tokens:createtime`, token),
+ db.sortedSetRemove(`tokens:uid`, token),
+ db.sortedSetRemove(`tokens:lastSeen`, token),
+ db.sortedSetAdd(`tokens:createtime`, createTime, newToken),
+ db.sortedSetAdd(`tokens:uid`, uid, newToken),
+ ];
+
+ if (lastSeen) {
+ updates.push(db.sortedSetAdd(`tokens:lastSeen`, lastSeen, newToken));
+ }
+
+ await Promise.all(updates);
+
+ return newToken;
+};
+
+utils.tokens.delete = async (token) => {
+ await Promise.all([
+ db.delete(`token:${token}`),
+ db.sortedSetRemove(`tokens:createtime`, token),
+ db.sortedSetRemove(`tokens:uid`, token),
+ db.sortedSetRemove(`tokens:lastSeen`, token),
+ ]);
+};
-utils.log = async (token) => {
+utils.tokens.log = async (token) => {
await db.sortedSetAdd('tokens:lastSeen', Date.now(), token);
};
-utils.getLastSeen = async tokens => await db.sortedSetScores('tokens:lastSeen', tokens);
+utils.tokens.getLastSeen = async tokens => await db.sortedSetScores('tokens:lastSeen', tokens);
diff --git a/src/controllers/admin/settings.js b/src/controllers/admin/settings.js
index 3255680a1e..e13511816c 100644
--- a/src/controllers/admin/settings.js
+++ b/src/controllers/admin/settings.js
@@ -111,14 +111,6 @@ settingsController.social = async function (req, res) {
};
settingsController.api = async (req, res) => {
- const { tokens } = await meta.settings.get('core.api');
- const scores = await api.utils.getLastSeen(tokens.map(t => t.token));
-
- const [lastSeen, lastSeenISO] = tokens.reduce((memo, cur, idx) => {
- memo[0][cur.token] = scores[idx];
- memo[1][cur.token] = new Date(scores[idx]).toISOString();
- return memo;
- }, [{}, {}]);
-
- res.render('admin/settings/api', { lastSeen, lastSeenISO });
+ const tokens = await api.utils.tokens.list();
+ res.render('admin/settings/api', { tokens });
};
diff --git a/src/controllers/write/admin.js b/src/controllers/write/admin.js
index adac0a6ef2..b7ba39db10 100644
--- a/src/controllers/write/admin.js
+++ b/src/controllers/write/admin.js
@@ -28,3 +28,32 @@ Admin.getAnalyticsData = async (req, res) => {
units: req.query.units,
}));
};
+
+Admin.generateToken = async (req, res) => {
+ const { uid, description } = req.body;
+ const token = await api.utils.tokens.generate({ uid, description });
+ helpers.formatApiResponse(200, res, await api.utils.tokens.get(token));
+};
+
+Admin.getToken = async (req, res) => {
+ helpers.formatApiResponse(200, res, await api.utils.tokens.get(req.params.token));
+};
+
+Admin.updateToken = async (req, res) => {
+ const { uid, description } = req.body;
+ const { token } = req.params;
+
+ helpers.formatApiResponse(200, res, await api.utils.tokens.update(token, { uid, description }));
+};
+
+Admin.rollToken = async (req, res) => {
+ let { token } = req.params;
+
+ token = await api.utils.tokens.roll(token);
+ helpers.formatApiResponse(200, res, await api.utils.tokens.get(token));
+};
+
+Admin.deleteToken = async (req, res) => {
+ const { token } = req.params;
+ helpers.formatApiResponse(200, res, await api.utils.tokens.delete(token));
+};
diff --git a/src/meta/configs.js b/src/meta/configs.js
index ca53dc1494..180540811c 100644
--- a/src/meta/configs.js
+++ b/src/meta/configs.js
@@ -7,8 +7,6 @@ const winston = require('winston');
const db = require('../database');
const pubsub = require('../pubsub');
-const plugins = require('../plugins');
-const utils = require('../utils');
const Meta = require('./index');
const cacheBuster = require('./cacheBuster');
const defaults = require('../../install/data/defaults.json');
@@ -148,46 +146,6 @@ Configs.remove = async function (field) {
await db.deleteObjectField('config', field);
};
-Configs.registerHooks = () => {
- plugins.hooks.register('core', {
- hook: 'filter:settings.set',
- method: async ({ plugin, settings, quiet }) => {
- if (plugin === 'core.api' && Array.isArray(settings.tokens)) {
- // Generate tokens if not present already
- settings.tokens.forEach((set) => {
- if (set.token === '') {
- set.token = utils.generateUUID();
- }
-
- if (isNaN(parseInt(set.uid, 10))) {
- set.uid = 0;
- }
- });
- }
-
- return { plugin, settings, quiet };
- },
- });
-
- plugins.hooks.register('core', {
- hook: 'filter:settings.get',
- method: async ({ plugin, values }) => {
- if (plugin === 'core.api' && Array.isArray(values.tokens)) {
- values.tokens = values.tokens.map((tokenObj) => {
- tokenObj.uid = parseInt(tokenObj.uid, 10);
- if (tokenObj.timestamp) {
- tokenObj.timestampISO = new Date(parseInt(tokenObj.timestamp, 10)).toISOString();
- }
-
- return tokenObj;
- });
- }
-
- return { plugin, values };
- },
- });
-};
-
Configs.cookie = {
get: () => {
const cookie = {};
diff --git a/src/middleware/index.js b/src/middleware/index.js
index 0c44b5cfaf..adf53c8c5e 100644
--- a/src/middleware/index.js
+++ b/src/middleware/index.js
@@ -128,7 +128,7 @@ middleware.prepareAPI = function prepareAPI(req, res, next) {
middleware.logApiUsage = async function logApiUsage(req, res, next) {
if (req.headers.hasOwnProperty('authorization')) {
const [, token] = req.headers.authorization.split(' ');
- await api.utils.log(token);
+ await api.utils.tokens.log(token);
}
next();
diff --git a/src/plugins/index.js b/src/plugins/index.js
index f573202450..be634bb8fa 100644
--- a/src/plugins/index.js
+++ b/src/plugins/index.js
@@ -10,7 +10,6 @@ const request = require('request-promise-native');
const user = require('../user');
const posts = require('../posts');
-const meta = require('../meta');
const { pluginNamePattern, themeNamePattern, paths } = require('../constants');
@@ -125,7 +124,6 @@ Plugins.reload = async function () {
// Core hooks
posts.registerHooks();
- meta.configs.registerHooks();
// Deprecation notices
Plugins.hooks._deprecated.forEach((deprecation, hook) => {
diff --git a/src/routes/authentication.js b/src/routes/authentication.js
index e2b1cd73cf..8d5bee679e 100644
--- a/src/routes/authentication.js
+++ b/src/routes/authentication.js
@@ -6,10 +6,10 @@ const passportLocal = require('passport-local').Strategy;
const BearerStrategy = require('passport-http-bearer').Strategy;
const winston = require('winston');
-const meta = require('../meta');
const controllers = require('../controllers');
const helpers = require('../controllers/helpers');
const plugins = require('../plugins');
+const api = require('../api');
const { generateToken } = require('../middleware/csrf');
let loginStrategies = [];
@@ -45,8 +45,8 @@ Auth.getLoginStrategies = function () {
};
Auth.verifyToken = async function (token, done) {
- const { tokens = [] } = await meta.settings.get('core.api');
- const tokenObj = tokens.find(t => t.token === token);
+ const tokens = await api.utils.tokens.list();
+ const tokenObj = tokens.filter((t => t.token === token)).pop();
const uid = tokenObj ? tokenObj.uid : undefined;
if (uid !== undefined) {
diff --git a/src/routes/write/admin.js b/src/routes/write/admin.js
index 0cda6327fb..2571b8dd01 100644
--- a/src/routes/write/admin.js
+++ b/src/routes/write/admin.js
@@ -15,5 +15,11 @@ module.exports = function () {
setupApiRoute(router, 'get', '/analytics', [...middlewares], controllers.write.admin.getAnalyticsKeys);
setupApiRoute(router, 'get', '/analytics/:set', [...middlewares], controllers.write.admin.getAnalyticsData);
+ setupApiRoute(router, 'post', '/tokens', [...middlewares], controllers.write.admin.generateToken);
+ setupApiRoute(router, 'get', '/tokens/:token', [...middlewares], controllers.write.admin.getToken);
+ setupApiRoute(router, 'put', '/tokens/:token', [...middlewares], controllers.write.admin.updateToken);
+ setupApiRoute(router, 'delete', '/tokens/:token', [...middlewares], controllers.write.admin.deleteToken);
+ setupApiRoute(router, 'post', '/tokens/:token/roll', [...middlewares], controllers.write.admin.rollToken);
+
return router;
};
diff --git a/src/upgrades/3.2.0/migrate_api_tokens.js b/src/upgrades/3.2.0/migrate_api_tokens.js
new file mode 100644
index 0000000000..dadf84e07d
--- /dev/null
+++ b/src/upgrades/3.2.0/migrate_api_tokens.js
@@ -0,0 +1,38 @@
+'use strict';
+
+const assert = require('assert');
+const winston = require('winston');
+
+const db = require('../../database');
+const meta = require('../../meta');
+const api = require('../../api');
+
+module.exports = {
+ name: 'Migrate tokens away from sorted-list implementation',
+ timestamp: Date.UTC(2023, 4, 2),
+ method: async () => {
+ const { tokens = [] } = await meta.settings.get('core.api');
+
+ await Promise.all(tokens.map(async (tokenObj) => {
+ const { token, uid, description } = tokenObj;
+ await api.utils.tokens.add({ token, uid, description });
+ }));
+
+ // Validate
+ const oldCount = await db.sortedSetCard('settings:core.api:sorted-list:tokens');
+ const newCount = await db.sortedSetCard('tokens:createtime');
+ try {
+ if (oldCount > 0) {
+ assert.strictEqual(oldCount, newCount);
+ }
+
+ // Delete old tokens
+ await meta.settings.set('core.api', {
+ tokens: [],
+ });
+ await db.delete('settings:core.api:sorted-lists');
+ } catch (e) {
+ winston.warn('Old token count does not match migrated tokens count, leaving old tokens behind.');
+ }
+ },
+};
diff --git a/src/views/admin/partials/api/sorted-list/item.tpl b/src/views/admin/partials/api/sorted-list/item.tpl
deleted file mode 100644
index c34836e758..0000000000
--- a/src/views/admin/partials/api/sorted-list/item.tpl
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
-
- {{{ if uid }}}uid {uid}{{{ else }}}master{{{ end }}}
- {{{ if token }}}{{{ else }}}[[admin/settings/api:token-on-save]]{{{ end }}}
-
- {{{ if description }}}
- {description}
- {{{ else }}}
- [[admin/settings/api:no-description]]
- {{{ end }}}
-
- {./lastSeen}
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/src/views/admin/partials/api/sorted-list/form.tpl b/src/views/admin/partials/edit-token-modal.tpl
similarity index 71%
rename from src/views/admin/partials/api/sorted-list/form.tpl
rename to src/views/admin/partials/edit-token-modal.tpl
index 2f129b43e4..87644f6dcd 100644
--- a/src/views/admin/partials/api/sorted-list/form.tpl
+++ b/src/views/admin/partials/edit-token-modal.tpl
@@ -1,15 +1,13 @@
-
\ No newline at end of file
diff --git a/src/views/admin/settings/api.tpl b/src/views/admin/settings/api.tpl
index 19af4cb568..b348f22d82 100644
--- a/src/views/admin/settings/api.tpl
+++ b/src/views/admin/settings/api.tpl
@@ -1,14 +1,76 @@
diff --git a/test/api.js b/test/api.js
index fb850da632..6eddd17f52 100644
--- a/test/api.js
+++ b/test/api.js
@@ -56,8 +56,23 @@ describe('API', async () => {
example: '', // to be defined later...
},
],
+ '/admin/tokens/{token}': [
+ {
+ in: 'path',
+ name: 'token',
+ example: '', // to be defined later...
+ },
+ ],
+ },
+ post: {
+ '/admin/tokens/{token}/roll': [
+ {
+ in: 'path',
+ name: 'token',
+ example: '', // to be defined later...
+ },
+ ],
},
- post: {},
put: {
'/groups/{slug}/pending/{uid}': [
{
@@ -71,6 +86,13 @@ describe('API', async () => {
example: '', // to be defined later...
},
],
+ '/admin/tokens/{token}': [
+ {
+ in: 'path',
+ name: 'token',
+ example: '', // to be defined later...
+ },
+ ],
},
patch: {},
delete: {
@@ -134,6 +156,13 @@ describe('API', async () => {
example: '', // to be defined later...
},
],
+ '/admin/tokens/{token}': [
+ {
+ in: 'path',
+ name: 'token',
+ example: '', // to be defined later...
+ },
+ ],
},
};
@@ -170,6 +199,16 @@ describe('API', async () => {
}
await groups.join('administrators', adminUid);
+ // Create api token for testing read/updating/deletion
+ const token = await api.utils.tokens.generate({ uid: adminUid });
+ mocks.get['/admin/tokens/{token}'][0].example = token;
+ mocks.put['/admin/tokens/{token}'][0].example = token;
+ mocks.delete['/admin/tokens/{token}'][0].example = token;
+
+ // Create another token for testing rolling
+ const token2 = await api.utils.tokens.generate({ uid: adminUid });
+ mocks.post['/admin/tokens/{token}/roll'][0].example = token2;
+
// Create sample group
await groups.create({
name: 'Test Group',
diff --git a/test/authentication.js b/test/authentication.js
index 7bb99687ee..60be72e457 100644
--- a/test/authentication.js
+++ b/test/authentication.js
@@ -15,6 +15,7 @@ const utils = require('../src/utils');
const meta = require('../src/meta');
const plugins = require('../src/plugins');
const privileges = require('../src/privileges');
+const api = require('../src/api');
const helpers = require('./helpers');
describe('authentication', () => {
@@ -596,24 +597,14 @@ describe('authentication', () => {
let masterToken;
before(async () => {
newUid = await user.create({ username: 'apiUserTarget' });
- const settings = await meta.settings.get('core.api');
- settings.tokens = settings.tokens || [];
- userToken = {
- token: utils.generateUUID(),
+ userToken = await api.utils.tokens.generate({
uid: newUid,
description: `api token for uid ${newUid}`,
- timestamp: Date.now(),
- };
- settings.tokens.push(userToken);
- masterToken = {
- token: utils.generateUUID(),
+ });
+ masterToken = await api.utils.tokens.generate({
uid: 0,
description: 'api master token',
- timestamp: Date.now(),
- };
- settings.tokens.push(masterToken);
-
- await meta.settings.set('core.api', settings);
+ });
});
it('should fail with invalid token', async () => {
@@ -635,7 +626,7 @@ describe('authentication', () => {
const { res, body } = await helpers.request('get', `/api/self`, {
json: true,
headers: {
- Authorization: `Bearer ${userToken.token}`,
+ Authorization: `Bearer ${userToken}`,
},
});
@@ -648,7 +639,7 @@ describe('authentication', () => {
form: {},
json: true,
headers: {
- Authorization: `Bearer ${masterToken.token}`,
+ Authorization: `Bearer ${masterToken}`,
},
});
@@ -663,7 +654,7 @@ describe('authentication', () => {
},
json: true,
headers: {
- Authorization: `Bearer ${masterToken.token}`,
+ Authorization: `Bearer ${masterToken}`,
},
});
diff --git a/test/tokens.js b/test/tokens.js
new file mode 100644
index 0000000000..2af4221bac
--- /dev/null
+++ b/test/tokens.js
@@ -0,0 +1,178 @@
+'use strict';
+
+const assert = require('assert');
+const nconf = require('nconf');
+
+const db = require('./mocks/databasemock');
+const api = require('../src/api');
+const user = require('../src/user');
+const utils = require('../src/utils');
+
+describe('API tokens', () => {
+ let token;
+
+ beforeEach(async () => {
+ // Generate a different token for use in each test
+ token = await api.utils.tokens.generate({ uid: 0 });
+ });
+
+ describe('.list()', () => {
+ it('should list available tokens', async () => {
+ await api.utils.tokens.generate({ uid: 0 });
+ const tokens = await api.utils.tokens.list();
+
+ assert(Array.isArray(tokens));
+ assert.strictEqual(tokens.length, 2);
+ assert.strictEqual(parseInt(tokens[0].uid, 10), 0);
+ assert.strictEqual(parseInt(tokens[1].uid, 10), 0);
+ });
+ });
+
+ describe('.create()', () => {
+ it('should fail to create a token for a user that does not exist', async () => {
+ assert.rejects(api.utils.tokens.generate({ uid: 1 }), { message: '[[error:no-user]]' });
+ });
+
+ it('should create a token for a user that exists', async () => {
+ const uid = await user.create({ username: utils.generateUUID().slice(0, 8) });
+ const token = await api.utils.tokens.generate({ uid });
+ const tokenObj = await api.utils.tokens.get(token);
+
+ assert(tokenObj);
+ assert.strictEqual(parseInt(tokenObj.uid, 10), uid);
+ });
+ });
+
+ describe('.get()', () => {
+ it('should retrieve a token', async () => {
+ const tokenObj = await api.utils.tokens.get(token);
+
+ assert(tokenObj);
+ assert.strictEqual(parseInt(tokenObj.uid, 10), 0);
+ });
+
+ it('should retrieve multiple tokens', async () => {
+ const second = await api.utils.tokens.generate({ uid: 0 });
+ const tokens = await api.utils.tokens.get([token, second]);
+
+ assert(Array.isArray(tokens));
+ tokens.forEach((t) => {
+ assert(t);
+ assert.strictEqual(parseInt(t.uid, 10), 0);
+ });
+ });
+
+ it('should fail if you pass in invalid data', async () => {
+ assert.rejects(api.utils.tokens.get(token), { message: '[[error:invalid-data]]' });
+ });
+
+ it('should show lastSeen and lastSeenISO as undefined/null if it is a new token', async () => {
+ const { lastSeen, lastSeenISO } = await api.utils.tokens.get(token);
+
+ assert.strictEqual(lastSeen, null);
+ assert.strictEqual(lastSeenISO, null);
+ });
+
+ it('should show lastSeenISO as an ISO formatted datetime string if the token has been used', async () => {
+ const now = new Date();
+ await db.sortedSetAdd('tokens:lastSeen', now.getTime(), token);
+ const { lastSeen, lastSeenISO } = await api.utils.tokens.get(token);
+
+ assert.strictEqual(lastSeen, now.getTime());
+ assert.strictEqual(lastSeenISO, now.toISOString());
+ });
+ });
+
+ describe('.generate()', () => {
+ it('should generate a new token', async () => {
+ const second = await api.utils.tokens.generate({ uid: 0 });
+ const token = await api.utils.tokens.get(second);
+
+ assert(token);
+ assert(await db.exists(`token:${second}`));
+ assert.equal(await db.sortedSetScore(`tokens:uid`, second), 0);
+ assert.strictEqual(parseInt(token.uid, 10), 0);
+ });
+ });
+
+ describe('.update()', () => {
+ it('should update the description of a token', async () => {
+ await api.utils.tokens.update(token, { uid: 0, description: 'foobar' });
+ const tokenObj = await api.utils.tokens.get(token);
+
+ assert(tokenObj);
+ assert.strictEqual(parseInt(tokenObj.uid, 10), 0);
+ assert.strictEqual(tokenObj.description, 'foobar');
+ });
+
+ it('should update the uid of a token', async () => {
+ await api.utils.tokens.update(token, { uid: 1, description: 'foobar' });
+ const tokenObj = await api.utils.tokens.get(token);
+ const uid = await db.sortedSetScore('tokens:uid', token);
+
+ assert(tokenObj);
+ assert.strictEqual(parseInt(tokenObj.uid, 10), 1);
+ assert.strictEqual(parseInt(uid, 10), 1);
+ assert.strictEqual(tokenObj.description, 'foobar');
+ });
+ });
+
+ describe('.roll()', () => {
+ it('should invalidate the old token', async () => {
+ const newToken = await api.utils.tokens.roll(token);
+ assert(newToken);
+
+ const gets = await api.utils.tokens.get([token, newToken]);
+ assert.strictEqual(gets[0], null);
+ assert(gets[1]);
+ });
+
+ it('should change a token but leave all other metadata intact', async () => {
+ await api.utils.tokens.update(token, { uid: 1, description: 'foobar' });
+ const newToken = await api.utils.tokens.roll(token);
+ const tokenObj = await api.utils.tokens.get(newToken);
+
+ assert.strictEqual(parseInt(tokenObj.uid, 10), 1);
+ assert.strictEqual(tokenObj.description, 'foobar');
+ });
+ });
+
+ describe('.delete()', () => {
+ it('should delete a token from a system', async () => {
+ await api.utils.tokens.delete(token);
+
+ assert.strictEqual(await db.exists(`token:${token}`), false);
+ assert.strictEqual(await db.sortedSetScore(`tokens:uid`, token), null);
+ assert.strictEqual(await db.sortedSetScore(`tokens:createtime`, token), null);
+ assert.strictEqual(await db.sortedSetScore(`tokens:lastSeen`, token), null);
+ });
+ });
+
+ describe('.log()', () => {
+ it('should record the current time as the last seen time of that token', async () => {
+ await api.utils.tokens.log(token);
+
+ assert(await db.sortedSetScore(`tokens:lastSeen`, token));
+ });
+ });
+
+ describe('.getLastSeen()', () => {
+ it('should retrieve the time the token was last seen', async () => {
+ await api.utils.tokens.log(token);
+ const time = await api.utils.tokens.getLastSeen([token]);
+
+ assert(time[0]);
+ assert(isFinite(time[0]));
+ });
+
+ it('should return null if the token has never been seen', async () => {
+ const time = await api.utils.tokens.getLastSeen([token]);
+
+ assert.strictEqual(time[0], null);
+ });
+ });
+
+ afterEach(async () => {
+ await api.utils.tokens.delete(token);
+ });
+});