Skip to content

Commit f31eb83

Browse files
authored
Merge pull request #3927 from NoelDeMartin/MOBILE-4304
MOBILE-4304: Replace WebSQL with sqlite-wasm
2 parents 829c59e + d944026 commit f31eb83

File tree

57 files changed

+2477
-1880
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2477
-1880
lines changed

.github/workflows/acceptance.yml

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,17 @@ jobs:
4141
working-directory: app
4242
run: npm run build:test
4343

44+
- name: Generate SSL certificates
45+
working-directory: app
46+
run: |
47+
mkdir ./ssl
48+
openssl req -x509 -nodes \
49+
-days 365 \
50+
-newkey rsa:2048 \
51+
-keyout ./ssl/certificate.key \
52+
-out ./ssl/certificate.crt \
53+
-subj="/O=Moodle"
54+
4455
- name: Build Behat plugin
4556
working-directory: app
4657
run: ./scripts/build-behat-plugin.js ../plugin
@@ -111,11 +122,12 @@ jobs:
111122

112123
- uses: actions/cache/save@v4
113124
with:
114-
key: build-${{ github.sha }}
115-
path: |
116-
app/node_modules/**/*
117-
app/www/**/*
118-
plugin/**/*
125+
key: build-${{ github.sha }}
126+
path: |
127+
app/ssl/**/*
128+
app/node_modules/**/*
129+
app/www/**/*
130+
plugin/**/*
119131
120132
behat:
121133
runs-on: ubuntu-latest
@@ -157,23 +169,33 @@ jobs:
157169
with:
158170
key: build-${{ github.sha }}
159171
path: |
172+
app/ssl/**/*
160173
app/node_modules/**/*
161174
app/www/**/*
162175
plugin/**/*
163176
164177
- name: Launch Docker images
165178
working-directory: app
166179
run: |
167-
docker run -d --rm -p 8001:80 --name moodleapp -v ./www:/usr/share/nginx/html -v ./nginx.conf:/etc/nginx/conf.d/default.conf nginx:alpine
180+
docker run -d --rm \
181+
-p 8001:443 \
182+
--name moodleapp \
183+
-v ./www:/usr/share/nginx/html \
184+
-v ./nginx.conf:/etc/nginx/conf.d/default.conf \
185+
-v ./ssl/certificate.crt:/etc/ssl/certificate.crt \
186+
-v ./ssl/certificate.key:/etc/ssl/certificate.key \
187+
nginx:alpine
168188
docker run -d --rm -p 8002:80 --name bigbluebutton moodlehq/bigbluebutton_mock:latest
169189
170190
- name: Initialise moodle-plugin-ci
171191
run: |
172-
composer create-project -n --no-dev --prefer-dist moodlehq/moodle-plugin-ci ci ^4.3
192+
git clone https://github.com/NoelDeMartin/moodle-plugin-ci --branch selenium-env ci
193+
composer install -d ./ci
173194
echo $(cd ci/bin; pwd) >> $GITHUB_PATH
174195
echo $(cd ci/vendor/bin; pwd) >> $GITHUB_PATH
175196
sudo locale-gen en_AU.UTF-8
176197
echo "NVM_DIR=$HOME/.nvm" >> $GITHUB_ENV
198+
sed -i "58i\$CFG->behat_profiles['chrome']['capabilities'] = ['extra_capabilities' => ['chromeOptions' => ['args' => ['--ignore-certificate-errors', '--allow-running-insecure-content']]]];" ci/res/template/config.php.txt
177199
178200
- name: Install Behat Snapshots plugin
179201
run: moodle-plugin-ci add-plugin NoelDeMartin/moodle-local_behatsnapshots
@@ -184,7 +206,7 @@ jobs:
184206
DB: pgsql
185207
MOODLE_BRANCH: ${{ github.event.inputs.moodle_branch || 'main' }}
186208
MOODLE_REPO: ${{ github.event.inputs.moodle_repository || 'https://github.com/moodle/moodle.git' }}
187-
MOODLE_BEHAT_IONIC_WWWROOT: http://localhost:8001
209+
MOODLE_BEHAT_IONIC_WWWROOT: https://localhost:8001
188210
MOODLE_BEHAT_DEFAULT_BROWSER: chrome
189211

190212
- name: Update config
@@ -194,6 +216,7 @@ jobs:
194216
run: moodle-plugin-ci behat --auto-rerun 3 --profile chrome --tags="@app&&~@local&&$BEHAT_TAGS"
195217
env:
196218
BEHAT_TAGS: ${{ matrix.tags }}
219+
MOODLE_BEHAT_SELENIUM_IMAGE: selenium/standalone-chrome:120.0
197220

198221
- name: Upload Snapshot failures
199222
uses: actions/upload-artifact@v4

Dockerfile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,17 @@ ARG build_command="npm run build:prod"
2323
COPY . /app
2424
RUN ${build_command}
2525

26+
# Generate SSL certificate
27+
RUN mkdir /app/ssl
28+
RUN openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /app/ssl/certificate.key -out /app/ssl/certificate.crt -subj="/O=Moodle"
29+
2630
## SERVE STAGE
2731
FROM nginx:alpine as serve-stage
2832

2933
# Copy assets & config
3034
COPY --from=build-stage /app/www /usr/share/nginx/html
35+
COPY --from=build-stage /app/ssl/certificate.crt /etc/ssl/certificate.crt
36+
COPY --from=build-stage /app/ssl/certificate.key /etc/ssl/certificate.key
3137
COPY ./nginx.conf /etc/nginx/conf.d/default.conf
32-
HEALTHCHECK --interval=10s --timeout=4s CMD curl -f http://localhost/assets/env.json || exit 1
38+
EXPOSE 443
39+
HEALTHCHECK --interval=10s --timeout=4s CMD curl --insecure -f https://localhost/assets/env.json || exit 1

angular.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,11 @@
9595
"options": {
9696
"disableHostCheck": true,
9797
"port": 8100,
98-
"buildTarget": "app:build"
98+
"buildTarget": "app:build",
99+
"headers": {
100+
"Cross-Origin-Opener-Policy": "same-origin",
101+
"Cross-Origin-Embedder-Policy": "require-corp"
102+
}
99103
},
100104
"configurations": {
101105
"production": {

local_moodleappbehat/tests/behat/behat_app.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -936,6 +936,38 @@ public function the_app_should_have_opened_a_browser_tab(bool $not = false, ?str
936936
});
937937
}
938938

939+
/**
940+
* Check that the app opened a url.
941+
*
942+
* @Then /^the app should( not)? have opened url "([^"]+)"(?: with contents "([^"]+)")?(?: (once|\d+ times))?$/
943+
* @param bool $not Whether to check if the app did not open the url
944+
* @param string $urlpattern Url pattern
945+
* @param string $contents Url contents
946+
* @param string $times How many times the url should have been opened
947+
*/
948+
public function the_app_should_have_opened_url(bool $not, string $urlpattern, ?string $contents = null, ?string $times = null) {
949+
if (is_null($times) || $times === 'once') {
950+
$times = 1;
951+
} else {
952+
$times = intval(substr($times, 0, strlen($times) - 6));
953+
}
954+
955+
$this->spin(function() use ($not, $urlpattern, $contents, $times) {
956+
$result = $this->runtime_js("hasOpenedUrl('$urlpattern', '$contents', $times)");
957+
958+
// TODO process times
959+
if ($not && $result === 'OK') {
960+
throw new DriverException('Error, an url was opened that should not have');
961+
}
962+
963+
if (!$not && $result !== 'OK') {
964+
throw new DriverException('Error asserting that url was opened - ' . $result);
965+
}
966+
967+
return true;
968+
});
969+
}
970+
939971
/**
940972
* Switches to a newly-opened browser tab.
941973
*

nginx.conf

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,23 @@
11
server {
2-
listen 0.0.0.0:80;
2+
listen 80;
3+
listen 443 ssl;
34
root /usr/share/nginx/html;
45
server_tokens off;
56
access_log off;
67

8+
# Configure SSL
9+
if ($scheme = "http") {
10+
return 301 https://$host$request_uri;
11+
}
12+
13+
ssl_certificate /etc/ssl/certificate.crt;
14+
ssl_certificate_key /etc/ssl/certificate.key;
15+
ssl_protocols TLSv1.3;
16+
17+
# Enable OPFS
18+
add_header Cross-Origin-Opener-Policy "same-origin";
19+
add_header Cross-Origin-Embedder-Policy "require-corp";
20+
721
location / {
822
try_files $uri $uri/ /index.html;
923
}

package-lock.json

Lines changed: 9 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
],
2020
"scripts": {
2121
"ng": "ng",
22-
"start": "ionic serve --browser=$MOODLE_APP_BROWSER",
22+
"start": "ionic serve --browser=$MOODLE_APP_BROWSER --ssl",
2323
"serve:test": "NODE_ENV=testing ionic serve --no-open",
2424
"build": "ionic build",
2525
"build:prod": "NODE_ENV=production ionic build --prod",
@@ -88,6 +88,7 @@
8888
"@moodlehq/phonegap-plugin-push": "4.0.0-moodle.7",
8989
"@ngx-translate/core": "^15.0.0",
9090
"@ngx-translate/http-loader": "^8.0.0",
91+
"@sqlite.org/sqlite-wasm": "^3.45.0-build1",
9192
"@types/chart.js": "^2.9.31",
9293
"@types/cordova": "0.0.34",
9394
"@types/dom-mediacapture-record": "1.0.7",
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
diff --git a/node_modules/@sqlite.org/sqlite-wasm/sqlite-wasm/jswasm/sqlite3-bundler-friendly.mjs b/node_modules/@sqlite.org/sqlite-wasm/sqlite-wasm/jswasm/sqlite3-bundler-friendly.mjs
2+
index b86a0aa..1be2b82 100644
3+
--- a/node_modules/@sqlite.org/sqlite-wasm/sqlite-wasm/jswasm/sqlite3-bundler-friendly.mjs
4+
+++ b/node_modules/@sqlite.org/sqlite-wasm/sqlite-wasm/jswasm/sqlite3-bundler-friendly.mjs
5+
@@ -533,7 +533,7 @@ var sqlite3InitModule = (() => {
6+
wasmBinaryFile = locateFile(wasmBinaryFile);
7+
}
8+
} else {
9+
- wasmBinaryFile = new URL('sqlite3.wasm', import.meta.url).href;
10+
+ wasmBinaryFile = '/assets/lib/sqlite3/sqlite3.wasm';
11+
}
12+
13+
function getBinary(file) {
14+
@@ -10913,6 +10913,10 @@ var sqlite3InitModule = (() => {
15+
}
16+
},
17+
18+
+ lastInsertRowId: function () {
19+
+ return capi.sqlite3_last_insert_rowid(affirmDbOpen(this).pointer);
20+
+ },
21+
+
22+
dbFilename: function (dbName = 'main') {
23+
return capi.sqlite3_db_filename(affirmDbOpen(this).pointer, dbName);
24+
},
25+
@@ -11877,12 +11881,14 @@ var sqlite3InitModule = (() => {
26+
if (!hadColNames) rc.columnNames = [];
27+
28+
rc.callback = function (row, stmt) {
29+
+ const rowId = rc.sql.includes('INSERT') ? db.lastInsertRowId() : undefined;
30+
wState.post(
31+
{
32+
type: theCallback,
33+
columnNames: rc.columnNames,
34+
rowNumber: ++rowNumber,
35+
row: row,
36+
+ rowId,
37+
},
38+
wState.xfer,
39+
);
40+
@@ -12522,7 +12528,7 @@ var sqlite3InitModule = (() => {
41+
return promiseResolve_(sqlite3);
42+
};
43+
const W = new Worker(
44+
- new URL('sqlite3-opfs-async-proxy.js', import.meta.url),
45+
+ '/assets/lib/sqlite3/sqlite3-opfs-async-proxy.js',
46+
);
47+
setTimeout(() => {
48+
if (undefined === promiseWasRejected) {
49+
@@ -13445,7 +13451,7 @@ var sqlite3InitModule = (() => {
50+
});
51+
return thePromise;
52+
};
53+
- installOpfsVfs.defaultProxyUri = 'sqlite3-opfs-async-proxy.js';
54+
+ installOpfsVfs.defaultProxyUri = '/assets/lib/sqlite3/sqlite3-opfs-async-proxy.js';
55+
globalThis.sqlite3ApiBootstrap.initializersAsync.push(
56+
async (sqlite3) => {
57+
try {

scripts/copy-assets.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ const ASSETS = {
3131
'/src/core/features/h5p/assets': '/lib/h5p',
3232
'/node_modules/ogv/dist': '/lib/ogv',
3333
'/node_modules/video.js/dist/video-js.min.css': '/lib/video.js/video-js.min.css',
34+
'/node_modules/@sqlite.org/sqlite-wasm/sqlite-wasm/jswasm/sqlite3.wasm': '/lib/sqlite3/sqlite3.wasm',
35+
'/node_modules/@sqlite.org/sqlite-wasm/sqlite-wasm/jswasm/sqlite3-opfs-async-proxy.js': '/lib/sqlite3/sqlite3-opfs-async-proxy.js',
3436
};
3537

3638
module.exports = function(ctx) {
313 Bytes
Loading

0 commit comments

Comments
 (0)