diff --git a/appinfo/routes.php b/appinfo/routes.php
index 6cd6bf5..a9fb817 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -6,6 +6,8 @@ return [
],
'routes' => [
['name' => 'server#records', 'url' => '/server/{roomUid}/records', 'verb' => 'GET'],
+ ['name' => 'server#check', 'url' => '/server/check', 'verb' => 'POST'],
+ ['name' => 'server#version', 'url' => '/server/version', 'verb' => 'GET'],
['name' => 'server#delete_record', 'url' => '/server/record/{recordId}', 'verb' => 'DELETE'],
['name' => 'join#index', 'url' => '/b/{token}', 'verb' => 'GET'],
['name' => 'room_api#preflighted_cors', 'url' => '/api/0.1/{path}',
diff --git a/lib/BigBlueButton/API.php b/lib/BigBlueButton/API.php
index d9c26f6..f56acf7 100644
--- a/lib/BigBlueButton/API.php
+++ b/lib/BigBlueButton/API.php
@@ -8,6 +8,7 @@ use BigBlueButton\Parameters\JoinMeetingParameters;
use BigBlueButton\Parameters\GetRecordingsParameters;
use BigBlueButton\Core\Record;
use BigBlueButton\Parameters\DeleteRecordingsParameters;
+use BigBlueButton\Parameters\IsMeetingRunningParameters;
use OCA\BigBlueButton\Db\Room;
use OCP\IConfig;
use OCP\IURLGenerator;
@@ -180,4 +181,34 @@ class API
'metas' => $record->getMetas(),
];
}
+
+ public function check($url, $secret)
+ {
+ $server = new BigBlueButton($url, $secret);
+
+ $meetingParams = new IsMeetingRunningParameters('foobar');
+
+ try {
+ $response = $server->isMeetingRunning($meetingParams);
+
+ if (!$response->success() && !$response->failed()) {
+ return 'invalid-url';
+ }
+
+ if (!$response->success()) {
+ return 'invalid-secret';
+ }
+
+ return 'success';
+ } catch (\Exception $e) {
+ return 'invalid-url';
+ }
+ }
+
+ public function getVersion($url = null)
+ {
+ $server = $url === null ? $this->getServer() : new BigBlueButton($url, '');
+
+ return $server->getApiVersion()->getVersion();
+ }
}
diff --git a/lib/Controller/ServerController.php b/lib/Controller/ServerController.php
index b2955b2..72f4d80 100644
--- a/lib/Controller/ServerController.php
+++ b/lib/Controller/ServerController.php
@@ -76,4 +76,28 @@ class ServerController extends Controller
return new DataResponse($success);
}
+
+ public function check(string $url, string $secret)
+ {
+ if ($url === null || empty($url) || $secret === null || empty($secret)) {
+ return new DataResponse(false);
+ }
+
+ return new DataResponse($this->server->check($url, $secret));
+ }
+
+ public function version(string $url)
+ {
+ if ($url === null || empty($url)) {
+ return new DataResponse(false, Http::STATUS_NOT_FOUND);
+ }
+
+ try {
+ $version = $this->server->getVersion($url);
+ } catch (\Exception $e) {
+ return new DataResponse(false, Http::STATUS_NOT_FOUND);
+ }
+
+ return new DataResponse($version);
+ }
}
diff --git a/templates/admin.php b/templates/admin.php
index 42491f7..9c08144 100644
--- a/templates/admin.php
+++ b/templates/admin.php
@@ -8,9 +8,13 @@ script('bbb', 'admin');
BigBlueButton
+
t('Get your API url and secret by executing "sudo bbb-conf --secret" on your BigBlueButton server.')); ?>
+
\ No newline at end of file
diff --git a/ts/Manager/Api.ts b/ts/Manager/Api.ts
index 6c9b788..10d89aa 100644
--- a/ts/Manager/Api.ts
+++ b/ts/Manager/Api.ts
@@ -75,6 +75,15 @@ class Api {
return response.data;
}
+
+ public async checkServer(url: string, secret: string): Promise<'success'|'invalid-url'|'invalid:secret'> {
+ const response = await axios.post(this.getUrl('server/check'), {
+ url,
+ secret,
+ });
+
+ return response.data;
+ }
}
export const api = new Api();
diff --git a/ts/Manager/App.scss b/ts/Manager/App.scss
index 9dc14b1..3c6a7e6 100644
--- a/ts/Manager/App.scss
+++ b/ts/Manager/App.scss
@@ -1,5 +1,4 @@
#bbb-warning {
- margin: 3em;
padding: 1em;
background-color: rgb(255, 255, 123);
display: inline-block;
@@ -9,7 +8,37 @@
}
}
+#bbb-success {
+ padding: 1em;
+ background-color: rgb(176, 252, 132);
+ display: inline-block;
+
+ .icon {
+ display: inline-block;
+ }
+}
+
+#bbb-settings {
+ #bbb-warning,
+ #bbb-success {
+ margin: 1em 0;
+ }
+
+ [type="url"],
+ [type="password"] {
+ width: 250px;
+ }
+
+ p {
+ margin-bottom: 1em;
+ }
+}
+
#bbb-react-root {
+ #bbb-warning,
+ #bbb-success {
+ margin: 3em;
+ }
.icon {
display: inline-block;
diff --git a/ts/Manager/Nextcloud.d.ts b/ts/Manager/Nextcloud.d.ts
index c63bf4a..550f526 100644
--- a/ts/Manager/Nextcloud.d.ts
+++ b/ts/Manager/Nextcloud.d.ts
@@ -46,6 +46,12 @@ declare namespace OC {
}
}
+ namespace PasswordConfirmation {
+ function requiresPasswordConfirmation(): boolean;
+
+ function requirePasswordConfirmation(cb: () => void): void;
+ }
+
function generateUrl(url: string, parameters?: { [key: string]: string }, options?: EscapeOptions)
function linkToOCS(service: string, version: number): string;
diff --git a/ts/admin.ts b/ts/admin.ts
index ec847b5..c91b661 100644
--- a/ts/admin.ts
+++ b/ts/admin.ts
@@ -1,10 +1,70 @@
+import {api} from './Manager/Api';
+import './Manager/App.scss';
+
declare const OCP: any;
$(() => {
+ function generateWarningElement(message: string) {
+ return $(` ${message}
`);
+ }
+
+ function generateSuccessElement(message: string) {
+ return $(` ${message}
`);
+ }
+
+ async function checkServer(url: string, secret: string) {
+ const result = await api.checkServer(url, secret);
+
+ if (result === 'success') {
+ return;
+ }
+
+ throw result;
+ }
+
+ function checkPasswordConfirmation() {
+ return new Promise(resolve => {
+ if (OC.PasswordConfirmation && OC.PasswordConfirmation.requiresPasswordConfirmation()) {
+ OC.PasswordConfirmation.requirePasswordConfirmation(() => resolve());
+
+ return;
+ }
+
+ resolve();
+ });
+ }
+
+ async function saveSettings(url: string, secret: string) {
+ url += url.endsWith('/') ? '' : '/';
+
+ await checkServer(url, secret);
+ await checkPasswordConfirmation();
+
+ OCP.AppConfig.setValue('bbb', 'api.url', url);
+ OCP.AppConfig.setValue('bbb', 'api.secret', secret);
+ }
+
$('#bbb-settings form').submit(function (ev) {
ev.preventDefault();
- OCP.AppConfig.setValue('bbb', 'api.url', this['api.url'].value);
- OCP.AppConfig.setValue('bbb', 'api.secret', this['api.secret'].value);
+ $('#bbb-result').empty();
+
+ saveSettings(this['api.url'].value, this['api.secret'].value).then(() => {
+ const successElement = generateSuccessElement(t('bbb', 'Settings saved'));
+
+ $('#bbb-result').append(successElement);
+ }).catch(err => {
+ let message = t('bbb', 'Unexpected error occurred');
+
+ if (err === 'invalid-url') {
+ message = t('bbb', 'API url is invalid');
+ } else if (err === 'invalid-secret') {
+ message = t('bbb', 'API secret is invalid');
+ }
+
+ const warningElement = generateWarningElement(message);
+
+ $('#bbb-result').append(warningElement);
+ });
});
});
\ No newline at end of file