You've already forked joplin
mirror of
https://github.com/laurent22/joplin.git
synced 2025-11-23 22:36:32 +02:00
135 lines
3.8 KiB
TypeScript
135 lines
3.8 KiB
TypeScript
import FileApiDriverJoplinServer from './file-api-driver-joplinServer';
|
|
import Setting from './models/Setting';
|
|
import { _ } from './locale.js';
|
|
import JoplinServerApi, { Session } from './JoplinServerApi';
|
|
import { FileApi } from './file-api';
|
|
import SyncTargetJoplinServer, { FileApiOptions } from './SyncTargetJoplinServer';
|
|
import Logger from '@joplin/utils/Logger';
|
|
|
|
export async function newFileApi(id: number, options: FileApiOptions) {
|
|
const apiOptions = {
|
|
baseUrl: () => options.path(),
|
|
userContentBaseUrl: () => options.userContentPath(),
|
|
username: () => '',
|
|
password: () => '',
|
|
session: () => ({ id: Setting.value('sync.11.id'), user_id: Setting.value('sync.11.userId') }),
|
|
env: Setting.value('env'),
|
|
};
|
|
|
|
const api = new JoplinServerApi(apiOptions);
|
|
const driver = new FileApiDriverJoplinServer(api);
|
|
const fileApi = new FileApi('', driver);
|
|
fileApi.setSyncTargetId(id);
|
|
await fileApi.initialize();
|
|
return fileApi;
|
|
}
|
|
|
|
export async function initFileApi(syncTargetId: number, logger: Logger, options: FileApiOptions) {
|
|
const fileApi = await newFileApi(syncTargetId, options);
|
|
fileApi.setLogger(logger);
|
|
return fileApi;
|
|
}
|
|
|
|
export const authenticateWithCode = async (code: string) => {
|
|
try {
|
|
const response = await fetch(`${Setting.value('sync.11.path')}/api/login_with_code/${code}`);
|
|
if (response.status !== 200) {
|
|
return false;
|
|
}
|
|
|
|
const token: Session = await response.json();
|
|
Setting.setValue('sync.11.id', token.id);
|
|
Setting.setValue('sync.11.userId', token.user_id);
|
|
|
|
} catch (_e) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
// A sync target for Joplin Server that uses SAML for authentication.
|
|
//
|
|
// Based on the regular Joplin Server sync target.
|
|
export default class SyncTargetJoplinServerSAML extends SyncTargetJoplinServer {
|
|
|
|
private lastFileApiOptions_: FileApiOptions|null = null;
|
|
|
|
public static override id() {
|
|
return 11;
|
|
}
|
|
|
|
public static override targetName() {
|
|
return 'joplinServerSaml';
|
|
}
|
|
|
|
public static override label() {
|
|
return `${_('Joplin Server (SAML)')}`;
|
|
}
|
|
|
|
public override async isAuthenticated() {
|
|
if (!Setting.value('sync.11.id')) return false;
|
|
|
|
// We check that the file API has been initialized at least once, otherwise the below check
|
|
// will always fail and it will be impossible to login.
|
|
if (this.lastFileApiOptions_) {
|
|
const check = await SyncTargetJoplinServer.checkConfig(null, null, await this.fileApi());
|
|
return check.ok;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
public static override requiresPassword() {
|
|
return false;
|
|
}
|
|
|
|
public static override async checkConfig(fileApi: FileApiOptions) {
|
|
try {
|
|
// Simulate a login request
|
|
const result = await fetch(`${fileApi.path()}/api/saml`);
|
|
|
|
if (result.status === 200) { // The server successfully responded, SAML is enabled
|
|
return {
|
|
ok: true,
|
|
errorMessage: '',
|
|
};
|
|
} else { // SAML is disabled or an error occurred
|
|
const text = await result.text();
|
|
let message = text; // Use the textual body as the default message
|
|
|
|
// Check if we got an error message
|
|
if (result.headers.get('Content-Type').includes('application/json')) {
|
|
try {
|
|
const json = JSON.parse(text);
|
|
|
|
if (json.error) {
|
|
message = json.error;
|
|
}
|
|
} catch (_e) {} // eslint-disable-line no-empty -- Keep the plain text response as the error message, ignore the parsing exception
|
|
}
|
|
|
|
return {
|
|
ok: false,
|
|
errorMessage: `Could not connect to server: Error ${result.status}: ${message}`,
|
|
};
|
|
}
|
|
} catch (e) {
|
|
return {
|
|
ok: false,
|
|
errorMessage: e.message,
|
|
};
|
|
}
|
|
}
|
|
|
|
protected override async initFileApi() {
|
|
this.lastFileApiOptions_ = {
|
|
path: () => Setting.value('sync.11.path'),
|
|
userContentPath: () => Setting.value('sync.11.userContentPath'),
|
|
username: () => '',
|
|
password: () => '',
|
|
};
|
|
return initFileApi(SyncTargetJoplinServerSAML.id(), this.logger(), this.lastFileApiOptions_);
|
|
}
|
|
}
|