Skip to content

Commit 4842812

Browse files
committed
sync with version opmaat.org
1 parent 1b1bfaf commit 4842812

24 files changed

Lines changed: 1509 additions & 527 deletions

.github/workflows/docker-image.yml

Lines changed: 41 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,50 @@
1-
name: Build and Publish Docker Image on Tag
1+
name: Build and Push Docker Image
22

33
on:
44
push:
5+
branches:
6+
- '**' # all branches
57
tags:
6-
- 'v*' # Trigger the workflow when a new tag starting with 'v' is pushed
8+
- 'v*' # tags
79

810
jobs:
9-
build:
11+
docker:
1012
runs-on: ubuntu-latest
1113

12-
permissions:
13-
actions: read
14-
contents: read
15-
packages: write
16-
1714
steps:
18-
# Step 1: Set up Docker Buildx (supports layer caching)
19-
- name: Set up Docker Buildx
20-
uses: docker/setup-buildx-action@v2
21-
22-
# Step 2: Restore cache for Docker layers
23-
- name: Cache Docker layers
24-
uses: actions/cache@v4
25-
with:
26-
path: /tmp/.buildx-cache
27-
key: buildx-cache-${{ github.sha }}
28-
restore-keys: |
29-
buildx-cache-${{ github.sha }}
30-
buildx-cache-
31-
buildx
32-
33-
# Step 3: Check out the repository
34-
- name: Checkout repository
35-
uses: actions/checkout@v4
36-
37-
# # Step 4: Log in to registry
38-
- name: Log into registry
39-
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin
40-
41-
- name: Initialize cache directory
42-
run: mkdir -p /tmp/.buildx-cache
43-
44-
- name: Debug cache
45-
run: ls -l /tmp/.buildx-cache
46-
47-
# Step 5: Build and push the Docker image with caching
48-
- name: Build and Push Docker image
49-
run: |
50-
docker buildx build \
51-
--cache-from=type=local,src=/tmp/.buildx-cache \
52-
--cache-to=type=local,dest=/tmp/.buildx-cache,mode=max \
53-
--tag ghcr.io/ximeraproject/ximeraserver:${{ github.ref_name }} \
54-
--push .
15+
- name: Checkout source
16+
uses: actions/checkout@v4
17+
18+
- name: Set up Docker Buildx
19+
uses: docker/setup-buildx-action@v3
20+
21+
- name: Log in to Docker Hub
22+
uses: docker/login-action@v3
23+
with:
24+
username: ${{ secrets.DOCKER_USERNAME }}
25+
password: ${{ secrets.DOCKER_PASSWORD }}
26+
27+
- name: Extract Git ref and tag
28+
id: extract
29+
run: |
30+
echo "GIT_REF=${GITHUB_REF}" >> $GITHUB_OUTPUT
31+
echo "SHORT_SHA=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
32+
33+
# Extract sanitized branch name or tag
34+
if [[ "${GITHUB_REF}" == refs/heads/* ]]; then
35+
BRANCH_NAME="${GITHUB_REF#refs/heads/}"
36+
TAG_NAME=$(echo "${BRANCH_NAME}" | tr '[:upper:]' '[:lower:]' | sed 's#[^a-z0-9_.-]#-#g')
37+
elif [[ "${GITHUB_REF}" == refs/tags/* ]]; then
38+
TAG_NAME="${GITHUB_REF#refs/tags/}"
39+
else
40+
TAG_NAME="unknown"
41+
fi
42+
43+
echo "DOCKER_TAG=${TAG_NAME}" >> $GITHUB_OUTPUT
44+
45+
- name: Build and push Docker image
46+
uses: docker/build-push-action@v5
47+
with:
48+
context: .
49+
push: true
50+
tags: ghcr.io/ximeraproject/server:${{ steps.extract.outputs.DOCKER_TAG }}

app.js

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -185,10 +185,16 @@ passport.deserializeUser(function(id, done) {
185185
}
186186

187187
function private(req, res, next){
188-
basicAuth({
189-
users: { 'private': 'nietzichtbaar' },
190-
challenge: true
191-
})(req, res, next)
188+
if( config.privateUser !== "none" ) {
189+
// console.log("PRIVATE_USER = " + config.privateUser + ".");
190+
basicAuth({
191+
users: { [config.privateUser]: config.privateCred },
192+
challenge: true
193+
})(req, res, next)
194+
}
195+
else
196+
next()
197+
192198
}
193199

194200
function redirectUnnormalizeRepositoryName( req, res, next ) {
@@ -201,10 +207,10 @@ passport.deserializeUser(function(id, done) {
201207
return;
202208
}
203209
}
204-
// if(req.params.repository.indexOf('*') !== -1)
205-
// private(req,res,next)
206-
// else
207-
next()
210+
if(config.privateRepoWithStar == "1" && req.params.repository.indexOf('*') !== -1)
211+
private(req,res,next)
212+
else
213+
next()
208214
}
209215

210216
////////////////////////////////////////////////////////////////
@@ -280,9 +286,10 @@ passport.deserializeUser(function(id, done) {
280286
res.sendFile('views/install.sh', { root: __dirname });
281287
});
282288

283-
app.get('/', function(req,res) {
284-
res.render('index', { title: 'Home', landingPage: true });
285-
});
289+
app.get('/',
290+
page.defaultHomePage,
291+
// res.render('index', { title: 'Home', landingPage: true });
292+
);
286293

287294
////////////////////////////////////////////////////////////////
288295
// TinCan (aka Experience) API
@@ -560,7 +567,7 @@ passport.deserializeUser(function(id, done) {
560567
page.renderWithETag);
561568

562569
app.get('/repositories',
563-
// private,
570+
private,
564571
page.repositories)
565572

566573
app.post('/repositories',
@@ -572,29 +579,29 @@ passport.deserializeUser(function(id, done) {
572579
// private,
573580
redirectUnnormalizeRepositoryName,
574581
page.mostRecentMetadata,
575-
xourses.index );
576-
582+
xourses.index );
577583

578584
if(!module.parent){
579585
server.listen(app.get('port'), function(stream){
580586
console.log('Express server listening on port ' + app.get('port'));
581-
});
582-
}
583-
584-
// If nothing else matches, it is a 404
585-
app.use(function(req, res, next){
586-
res.status(404).render('404', { status: 404, url: req.url });
587-
});
587+
});
588+
}
588589

589-
////////////////////////////////////////////////////////////////
590-
// Present errors to the user
591-
592-
if ('development' == app.get('env')) {
593-
// Middleware for development only, since this will dump a
590+
// If nothing else matches, it is a 404
591+
app.use(function(req, res, next){
592+
res.status(404).render('404', { status: 404, url: req.url });
593+
});
594+
595+
////////////////////////////////////////////////////////////////
596+
// Present errors to the user
597+
598+
if ('development' == app.get('env')) {
599+
// Middleware for development only, since this will dump a
594600
// stack trace
601+
console.log('Running development version ');
595602
errorHandler.title = 'Ximera';
596-
app.use(errorHandler());
597-
}
603+
app.use(errorHandler());
604+
}
598605

599606
app.use(function(err, req, res, next){
600607
if (res.headersSent) {

config.js

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,12 +102,12 @@ config.smtp.address = process.env.SMTP_FROM_ADDRESS || 'ximera@math.o
102102
*/
103103

104104
config.localAuth = false;
105-
if (config.environment == 'development') {
106-
config.localAuth = true;
107-
}
105+
// if (config.environment == 'development') {
106+
// config.localAuth = true;
107+
// }
108108

109109
// Github
110-
config.githubAuth = true;
110+
config.githubAuth = process.env.GITHUB_AUTH ? true : false;
111111
config.github = {};
112112
config.github.clientID = process.env.GITHUB_CLIENT_ID || 'Your Key';
113113
config.github.clientSecret = process.env.GITHUB_CLIENT_SECRET || 'Your Secret';
@@ -133,5 +133,23 @@ config.lti.secret = process.env.LTI_SECRET || 'Your Secret';
133133
module.exports = config;
134134

135135

136-
config.brandHomeLink = process.env.BRAND_HOME_LINK || "https://ximera.org";
136+
// config.brandHomeLink = process.env.BRAND_HOME_LINK || "https://ximera.org";
137+
config.brandHomeLink = process.env.BRAND_HOME_LINK || config.root;
137138
config.brandLogo = process.env.BRAND_LOGO || "/public/images/logo/logo.svg";
139+
140+
config.privateUser = process.env.PRIVATE_USER || "private";
141+
config.privateCred = process.env.PRIVATE_CRED || "nietzichtbaar";
142+
config.privateRepoWithStar = process.env.PRIVATE_REPO_WITH_STAR || "1";
143+
144+
config.showLogin = process.env.SHOW_LOGIN ? true : false;
145+
config.showEdit = process.env.SHOW_EDIT ? true : false;
146+
147+
config.emailMain = process.env.EMAIL_MAIN || 'info@ximera.org';
148+
config.emailXourse = process.env.EMAIL_XOURSE || 'info@ximera.org';
149+
config.emailNameXourse = process.env.EMAIL_NAME_XOURSE || "Ximera Team";
150+
151+
152+
153+
config.homeRepo = process.env.HOMEPAGE_REPO || "";
154+
config.homeXourse = process.env.HOMEPAGE_XOURSE || "";
155+
config.homeActivity = process.env.HOMEPAGE_ACTIVITY || "";

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
{
22
"name": "ximera",
33
"description": "Ximera interactive textbook server",
4-
"version": "1.6.5",
4+
"version": "2.6.0",
55
"private": true,
66
"scripts": {
77
"start": "node app.js",
88
"test": "mocha --recursive",
9-
"build": "gulp"
9+
"build": "gulp",
10+
"build:js": "gulp js",
11+
"build:css": "gulp css"
1012
},
1113
"dependencies": {
1214
"annotator": "^2.0.0-alpha.3",

public/javascripts/database.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -491,12 +491,15 @@ module.exports.resetWork = clickResetWorkButton;
491491
$(document).ready(function() {
492492
activityHash = findActivityHash();
493493

494-
window.onbeforeunload = function() {
495-
// Before the page disappears, let's test to see if there is unsaved data
496-
if (jsondiffpatch.diff( SHADOW, DATABASE ) !== undefined) {
497-
return "There is unsaved data on this page.";
498-
}
499-
};
494+
//
495+
// 2025-03: REMOVED, as it pops up way too often
496+
//
497+
// window.onbeforeunload = function() {
498+
// // Before the page disappears, let's test to see if there is unsaved data
499+
// if (jsondiffpatch.diff( SHADOW, DATABASE ) !== undefined) {
500+
// return "There is unsaved data on this page.";
501+
// }
502+
// };
500503

501504
$(SAVE_WORK_BUTTON_ID).click( differentialSynchronization );
502505
$(RESET_WORK_BUTTON_ID).click( clickResetWorkButton );

0 commit comments

Comments
 (0)