Merge branch 'feat-kosync-onlongpress' of https://github.com/jpirnay/crosspoint-reader into mybuild
This commit is contained in:
@@ -102,14 +102,19 @@ STR_AUTHENTICATING: "Authenticating..."
|
||||
STR_AUTH_SUCCESS: "Successfully authenticated!"
|
||||
STR_KOREADER_AUTH: "KOReader Auth"
|
||||
STR_SYNC_READY: "KOReader sync is ready to use"
|
||||
STR_AUTH_FAILED: "Authentication Failed"
|
||||
STR_AUTH_FAILED: "Authentication failed"
|
||||
STR_REGISTER: "Register"
|
||||
STR_REGISTERING: "Registering..."
|
||||
STR_REGISTER_SUCCESS: "Account created successfully!"
|
||||
STR_REGISTER_FAILED: "Registration failed"
|
||||
STR_USERNAME_TAKEN: "Username already taken"
|
||||
STR_DONE: "Done"
|
||||
STR_CLEAR_CACHE_WARNING_1: "This will clear all cached book data."
|
||||
STR_CLEAR_CACHE_WARNING_2: "All reading progress will be lost!"
|
||||
STR_CLEAR_CACHE_WARNING_3: "Books will need to be re-indexed"
|
||||
STR_CLEAR_CACHE_WARNING_4: "when opened again."
|
||||
STR_CLEARING_CACHE: "Clearing cache..."
|
||||
STR_CACHE_CLEARED: "Cache Cleared"
|
||||
STR_CACHE_CLEARED: "Cache cleared"
|
||||
STR_ITEMS_REMOVED: "items removed"
|
||||
STR_FAILED_LOWER: "failed"
|
||||
STR_CLEAR_CACHE_FAILED: "Failed to clear cache"
|
||||
|
||||
@@ -28,6 +28,67 @@ void addAuthHeaders(HTTPClient& http) {
|
||||
bool isHttpsUrl(const std::string& url) { return url.rfind("https://", 0) == 0; }
|
||||
} // namespace
|
||||
|
||||
KOReaderSyncClient::Error KOReaderSyncClient::registerUser() {
|
||||
if (!KOREADER_STORE.hasCredentials()) {
|
||||
LOG_DBG("KOSync", "No credentials configured");
|
||||
return NO_CREDENTIALS;
|
||||
}
|
||||
|
||||
std::string url = KOREADER_STORE.getBaseUrl() + "/users/create";
|
||||
LOG_DBG("KOSync", "Registering user: %s", url.c_str());
|
||||
|
||||
HTTPClient http;
|
||||
std::unique_ptr<WiFiClientSecure> secureClient;
|
||||
WiFiClient plainClient;
|
||||
|
||||
if (isHttpsUrl(url)) {
|
||||
secureClient.reset(new WiFiClientSecure);
|
||||
secureClient->setInsecure();
|
||||
http.begin(*secureClient, url.c_str());
|
||||
} else {
|
||||
http.begin(plainClient, url.c_str());
|
||||
}
|
||||
|
||||
http.addHeader("Accept", "application/vnd.koreader.v1+json");
|
||||
http.addHeader("Content-Type", "application/json");
|
||||
|
||||
JsonDocument doc;
|
||||
doc["username"] = KOREADER_STORE.getUsername();
|
||||
doc["password"] = KOREADER_STORE.getMd5Password();
|
||||
std::string body;
|
||||
serializeJson(doc, body);
|
||||
|
||||
LOG_DBG("KOSync", "Register request body: <redacted credentials>");
|
||||
|
||||
const int httpCode = http.POST(body.c_str());
|
||||
const String responseBody = http.getString();
|
||||
http.end();
|
||||
|
||||
LOG_DBG("KOSync", "Register response: %d | body: %s", httpCode, responseBody.c_str());
|
||||
|
||||
if (httpCode == 201) {
|
||||
return OK;
|
||||
} else if (httpCode == 200) {
|
||||
// Some server implementations return 200 when the user already exists
|
||||
return USER_EXISTS;
|
||||
} else if (httpCode == 402) {
|
||||
// Both "user already exists" (error 2002) and "registration disabled" (error 2005)
|
||||
// return HTTP 402 on the original kosync server. Distinguish them by body text.
|
||||
String lowerBody = responseBody;
|
||||
lowerBody.toLowerCase();
|
||||
if (lowerBody.indexOf("already") >= 0) {
|
||||
return USER_EXISTS;
|
||||
}
|
||||
return REGISTRATION_DISABLED;
|
||||
} else if (httpCode == 409) {
|
||||
// korrosync returns 409 for existing users
|
||||
return USER_EXISTS;
|
||||
} else if (httpCode < 0) {
|
||||
return NETWORK_ERROR;
|
||||
}
|
||||
return SERVER_ERROR;
|
||||
}
|
||||
|
||||
KOReaderSyncClient::Error KOReaderSyncClient::authenticate() {
|
||||
if (!KOREADER_STORE.hasCredentials()) {
|
||||
LOG_DBG("KOSync", "No credentials configured");
|
||||
@@ -195,6 +256,10 @@ const char* KOReaderSyncClient::errorString(Error error) {
|
||||
return "JSON parse error";
|
||||
case NOT_FOUND:
|
||||
return "No progress found";
|
||||
case USER_EXISTS:
|
||||
return "Username is already taken";
|
||||
case REGISTRATION_DISABLED:
|
||||
return "Registration is disabled on this server";
|
||||
default:
|
||||
return "Unknown error";
|
||||
}
|
||||
|
||||
@@ -19,9 +19,10 @@ struct KOReaderProgress {
|
||||
* Base URL: https://sync.koreader.rocks:443/
|
||||
*
|
||||
* API Endpoints:
|
||||
* GET /users/auth - Authenticate (validate credentials)
|
||||
* GET /syncs/progress/:document - Get progress for a document
|
||||
* PUT /syncs/progress - Update progress for a document
|
||||
* POST /users/create - Register a new user
|
||||
* GET /users/auth - Authenticate (validate credentials)
|
||||
* GET /syncs/progress/:document - Get progress for a document
|
||||
* PUT /syncs/progress - Update progress for a document
|
||||
*
|
||||
* Authentication:
|
||||
* x-auth-user: username
|
||||
@@ -29,7 +30,24 @@ struct KOReaderProgress {
|
||||
*/
|
||||
class KOReaderSyncClient {
|
||||
public:
|
||||
enum Error { OK = 0, NO_CREDENTIALS, NETWORK_ERROR, AUTH_FAILED, SERVER_ERROR, JSON_ERROR, NOT_FOUND };
|
||||
enum Error {
|
||||
OK = 0,
|
||||
NO_CREDENTIALS,
|
||||
NETWORK_ERROR,
|
||||
AUTH_FAILED,
|
||||
SERVER_ERROR,
|
||||
JSON_ERROR,
|
||||
NOT_FOUND,
|
||||
USER_EXISTS,
|
||||
REGISTRATION_DISABLED
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a new user account with the sync server.
|
||||
* Uses credentials already stored in KOReaderCredentialStore.
|
||||
* @return OK on success, USER_EXISTS if taken, REGISTRATION_DISABLED if server disallows it
|
||||
*/
|
||||
static Error registerUser();
|
||||
|
||||
/**
|
||||
* Authenticate with the sync server (validate credentials).
|
||||
|
||||
Reference in New Issue
Block a user