Skip to content

Commit

Permalink
v0.14.0 (see NEWS)
Browse files Browse the repository at this point in the history
  • Loading branch information
nondeterministic committed Dec 30, 2022
1 parent 5f7dbd5 commit a832ec2
Show file tree
Hide file tree
Showing 25 changed files with 479 additions and 170 deletions.
20 changes: 20 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,26 @@
| |_| | |_| | _ <| |___| __/ | |\ | |___ \ V V / ___) |
\___/ \___/|_| \_\_____|_| |_| \_|_____| \_/\_/ |____/

v0.14.0 Wed Dec 28 17:39:17 CET 2022
--------------------------------------------------------
- Main features:
- Buttons for sharing repertory search results and opening them in
a new window
- Buttons for sharing and opening materia medica search results in
a new window
- OOREP window title always reflects last search now as to make
working with multiple tabs easier

- Minor improvements and changes:
- Move Play version to 2.8.18
- Move OpenJDK version to 11.0.16
- Renamed most of the $OOREP_X environment variables as to make
deployment easier

- Bug fixes:
- Fix race condition that would prevent public link to repertory
search from loading

v0.13.0 Thu May 26 12:13:11 PM CEST 2022
--------------------------------------------------------
- Main features:
Expand Down
40 changes: 25 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ can also be found at https://www.oorep.com/.
## Current status / what's new

Besides the aforementioned homepage, check out the [NEWS](NEWS) file for the
latest updates.
latest development updates.

## Running the program

Expand All @@ -33,8 +33,7 @@ $ docker-compose up
Depending on your Internet connection, those commands may take a while to complete.
When all is done, you should be able to point your web browser to `http://localhost:9000`
and see OOREP's landing page. Needless to say, those images are test-only and are not
intended for any production environments or the like without further modifications
and additions.
intended for any production environments or the like without further modifications.

### Method 2: By building the project from scratch (for experts only)

Expand All @@ -51,15 +50,25 @@ OOREP-database). The database needs to be named '`oorep`' and the PostgreSQL-use
owning it, '`oorep_user`'. Also, you will need to define the following environment
variables:

* `$OOREP_APPLICATION_HOST`: Usually something like `http://localhost:9000`
for development environments, or `https://www.oorep.com` for a production
environment (notice, no trailing slash)
* `$OOREP_APPLICATION_SECRET`: application-specific password you need to set
if you run the server using `https` instead of `http` (which I don't, since
I use a reverse proxy)
* `$OOREP_DB_HOST`: hostname of DB-server (e.g., localhost)
* `$OOREP_DB_PORT`: port of DB-server (usually 5432)
* `$OOREP_DB_PASS`: password used by the DB-user
* `$OOREP_APP_PROTOCOL`: usually either `http` or `https`
* `$OOREP_APP_HOSTNAME`: the part that follows `$OOREP_APP_PROTOCOL`,
such as `www`, for example, or any other hostname
* `$OOREP_APP_PORT`: port of application server (normally `9000`), but should only be
set if application server is directly used (i.e., do not set when using a reverse
proxy!)
* `$OOREP_APP_DOMAIN`: your domain name, e.g., `oorep.com`, but do not set when, for
example, you're merely using `localhost` as hostname
* `$OOREP_APP_SECRET`: application-specific password you need to set if you run the
application server using `https` instead of `http` (which I don't, since I use a
reverse proxy that does end-to-end encryption)
* `$OOREP_DB_NAME`: name of your PostgreSQL database; set to `oorep`, unless
you know better!
* `$OOREP_DB_USER`: name of your PostgreSQL database user; set to `oorep_user`, unless
you know better!
* `$OOREP_DB_PASS`: password of your PostgreSQL database; for test-environments,
use the one from within the `docker` directory of this repository, unless you know better!
* `$OOREP_DB_HOST`: full hostname of DB-server (e.g., `localhost` or `db.oorep.com`)
* `$OOREP_DB_PORT`: port of DB-server (usually `5432`)
* `$OOREP_URL_LOGOUT`: right now only mandatory if authentication is used:
the URL which users must click on in order to logout of OOREP (usually your
logout binding of an accompanying (SAML) Service Provider)
Expand All @@ -69,10 +78,11 @@ variables:
username on your SMTP server
* `$OOREP_MAIL_PASS`: right now only mandatory if authentication is used:
password for that username on your SMTP server

Check `backend/conf/application.conf` for their respective use, and make other
adjustments as you see fit there. Also be sure these variables are set before
attempting to execute the OOREP code using SBT.
adjustments as you see fit there (especially if you alter the domain variable).
Also be sure these variables are set before attempting to execute the OOREP code
using SBT.

#### Recommended external libraries

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class Get @Inject()(cc: ControllerComponents, dbContext: DBContext) extends Abst
Redirect(sys.env.get("OOREP_URL_LOGOUT").getOrElse(""))
case Some(uid) =>
Logger.debug(s"Get: login() completed for user ${uid.toString}.")
Redirect(sys.env.get("OOREP_APPLICATION_HOST").getOrElse(""))
Redirect(serverUrl(request))
.withCookies(
Cookie(CookieFields.id.toString, uid.toString, httpOnly = false),
Cookie(CookieFields.cookiePopupAccepted.toString, "1", httpOnly = false)
Expand All @@ -72,7 +72,11 @@ class Get @Inject()(cc: ControllerComponents, dbContext: DBContext) extends Abst
}

def show(repertory: String, symptom: String, page: Int, remedyString: String, minWeight: Int) = Action { request: Request[AnyContent] =>
Ok(views.html.index_lookup(request, repertory, symptom, page - 1, remedyString, minWeight, s"OOREP ${xml.Utility.escape("")} open online homeopathic repertory"))
Ok(views.html.index_lookup(request, repertory, symptom, page - 1, remedyString, minWeight, s"OOREP - ${symptom} (${repertory})"))
}

def showMM(materiaMedica: String, symptom: String, page: Int, hideSections: Boolean, remedyString: String) = Action { request: Request[AnyContent] =>
Ok(views.html.index_lookup_mm(request, materiaMedica, symptom, page - 1, hideSections, remedyString, s"OOREP - ${symptom} (${materiaMedica})"))
}

def serve_static_html(page: String) = Action { implicit request: Request[AnyContent] =>
Expand Down Expand Up @@ -290,12 +294,7 @@ class Get @Inject()(cc: ControllerComponents, dbContext: DBContext) extends Abst
}

// Used in HTML-templates/-files
object Get {
val staticServerUrl = {
sys.env.get("OOREP_APPLICATION_HOST") match {
case Some(host) => host
case _ => "https://www.oorep.com"
}
}
object Get extends ServerUrl {
val staticServerUrl = serverUrl()
val staticAssetsPath = "/assets/html"
}
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class Post @Inject()(cc: ControllerComponents, dbContext: DBContext) extends Abs

val f = Future {
send a new Mail(
from = ("info@oorep.com", "OOREP-Support"),
from = ("info@" + serverDomain(request), "OOREP-Support"),
to = member.email,
subject = "Username",
message = s"You (or someone else) has requested that your OOREP username be emailed\n" +
Expand Down Expand Up @@ -135,7 +135,7 @@ class Post @Inject()(cc: ControllerComponents, dbContext: DBContext) extends Abs

val randomIdString = genRandomString(30)
val requestDate = new MyDate()
val emailLink = sys.env.get("OOREP_APPLICATION_HOST").getOrElse("https://www.oorep.com") + "/change_password?id=" + randomIdString
val emailLink = "https://" + serverDomain(request) + "/change_password?id=" + randomIdString

dbContext.transaction {
// A member may at most have one password change request in the database
Expand All @@ -151,7 +151,7 @@ class Post @Inject()(cc: ControllerComponents, dbContext: DBContext) extends Abs

val f = Future {
send a new Mail(
from = ("info@oorep.com", "OOREP-Support"),
from = ("info@" + serverDomain(request), "OOREP-Support"),
to = member.email,
subject = "Password reset",
message = s"You (or someone else) has requested that you reset your OOREP password.\n\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,41 @@ import play.api.mvc._
trait ServerUrl {

def serverUrl(req: Request[AnyContent]) = {
val path = req.host
if (req.connection.secure)
"https://" + path
else
"http://" + path
(sys.env.get("OOREP_APP_PROTOCOL"), sys.env.get("OOREP_APP_HOSTNAME"), sys.env.get("OOREP_APP_DOMAIN"), sys.env.get("OOREP_APP_PORT")) match {
case (Some(protocol), Some(hostname), Some(domain), Some(port)) =>
protocol + "://" + hostname + "." + domain + ":" + port
case (Some(protocol), Some(hostname), Some(domain), None) =>
protocol + "://" + hostname + "." + domain
case (Some(protocol), Some(hostname), None, Some(port)) =>
protocol + "://" + hostname + ":" + port
case (Some(protocol), Some(hostname), None, None) =>
protocol + "://" + hostname
case _ =>
val path = req.host
if (req.connection.secure)
"https://" + path
else
"http://" + path
}
}

def serverUrl() = {
(sys.env.get("OOREP_APP_PROTOCOL"), sys.env.get("OOREP_APP_HOSTNAME"), sys.env.get("OOREP_APP_DOMAIN"), sys.env.get("OOREP_APP_PORT")) match {
case (Some(protocol), Some(hostname), Some(domain), Some(port)) =>
protocol + "://" + hostname + "." + domain + ":" + port
case (Some(protocol), Some(hostname), Some(domain), None) =>
protocol + "://" + hostname + "." + domain
case (Some(protocol), Some(hostname), None, Some(port)) =>
protocol + "://" + hostname + ":" + port
case (Some(protocol), Some(hostname), None, None) =>
protocol + "://" + hostname
case _ => "https://www.oorep.com/"
}
}

def serverDomain(req: Request[AnyContent]) =
sys.env.get("OOREP_DOMAIN").getOrElse(req.domain)

def apiPrefix() = "api"

}
6 changes: 3 additions & 3 deletions backend/app/views/index_lookup.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -62,17 +62,17 @@ <h1 style="font-size:20pt;">

@if(org.multics.baueran.frep.backend.controllers.getAuthenticatedUser(request) == None) {

<script async src="/assets/frontend-opt.js"></script>
<script src="/assets/frontend-opt.js"></script>

} else {

<script async src="/assets/sec_frontend-opt.js"></script>
<script src="/assets/sec_frontend-opt.js"></script>

}

<script>
$(document).ready(function(){
RepertoryView.doLookup("@repertory", "@symptom", "@page", "@remedyString", "@minWeight");
RepertoryView.doLookup("@repertory", "@symptom", @page, "@remedyString", @minWeight);
});
</script>

Expand Down
79 changes: 79 additions & 0 deletions backend/app/views/index_lookup_mm.scala.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
@(request: Request[AnyContent], materiaMedica: String, symptom: String, page: Int, hideSections: Boolean, remedyString: String, title: String)

@import org.multics.baueran.frep.backend.controllers._
@import org.multics.baueran.frep.shared.Defs._

@header = {
<link id="normaltheme" rel="stylesheet" href="@{org.multics.baueran.frep.backend.controllers.Get.staticAssetsPath}/third-party/bootstrap-4.3.1/css/bootstrap.min.css" @if(getFromRequestCookie(request, CookieFields.theme.toString).getOrElse("normal") == "dark") { disabled }>
<link id="darktheme" rel="stylesheet" href="@{org.multics.baueran.frep.backend.controllers.Get.staticAssetsPath}/third-party/bootstrap-4.3.1/css/bootstrap-darkly.min.css" @if(getFromRequestCookie(request, CookieFields.theme.toString).getOrElse("normal") == "normal") { disabled }>
<script src="@{org.multics.baueran.frep.backend.controllers.Get.staticAssetsPath}/third-party/jquery-3.5.1.min.js"></script>
<link rel="stylesheet" href="@{org.multics.baueran.frep.backend.controllers.Get.staticAssetsPath}/mystyle.css">

<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta property="og:image" content="@{org.multics.baueran.frep.backend.controllers.Get.staticServerUrl}@{org.multics.baueran.frep.backend.controllers.Get.staticAssetsPath}/img/oorep_screenshot_shared.jpg" />
<meta property="og:image:secure_url" content="@{org.multics.baueran.frep.backend.controllers.Get.staticServerUrl}@{org.multics.baueran.frep.backend.controllers.Get.staticAssetsPath}/img/oorep_screenshot_shared.jpg" />
<meta property="og:description" content="Free online repertory of homeopathy that requires only a web browser to run. Features many of the classical repertories, such as Kent, Boger, Hering, etc." />
<meta property="og:type" content="website" />

@if(remedyString.length > 0) {
<meta property="og:title" content="OOREP - chapter(s) for '@remedyString' in '@materiaMedica'" />
} else {
<meta property="og:title" content="OOREP - chapter(s) for '@symptom' in '@materiaMedica'" />
}

<meta name="description" content="Free online repertory of homeopathy that requires only a web browser to run. Features many of the classical repertories, such as Kent, Boger, Hering, etc." />
<meta name="keywords" content="oorep, online, repertory, homeopathy, repertorization, kent" />

<title>@title</title>
}

@main(title, header) {

@if(org.multics.baueran.frep.backend.controllers.getAuthenticatedUser(request) == None) {
@partial.cookiepopup(org.multics.baueran.frep.backend.controllers.Get.staticServerUrl)
}

@partial.navbar(org.multics.baueran.frep.backend.controllers.Get.staticServerUrl, request)

@partial.noscript_warning()

<div id="temporary_content">

<div style="width:100%;">
<div style="width:100%; margin-top:100px; margin-bottom:100px;" class="text-center">
<h1 style="font-size:20pt;">
<a href="@{org.multics.baueran.frep.backend.controllers.Get.staticServerUrl}/"><img src="@{org.multics.baueran.frep.backend.controllers.Get.staticAssetsPath}/img/logo_small.png" width="180" height="65" alt="OOREP"></a>
&nbsp; &middot; &nbsp; open online homeopathic repertory
</h1>
</div>

@partial.about()

@partial.features()

</div>

</div>

<div style="width:100%;" id="content"></div>

@partial.disclaimer()

@if(org.multics.baueran.frep.backend.controllers.getAuthenticatedUser(request) == None) {

<script src="/assets/frontend-opt.js"></script>

} else {

<script src="/assets/sec_frontend-opt.js"></script>

}

<script>
$(document).ready(function(){
MateriaMedicaView.doLookup("@materiaMedica", "@symptom", @page, @hideSections, "@remedyString");
});
</script>

}
4 changes: 2 additions & 2 deletions backend/app/views/partial/disclaimer.scala.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ <h4 style="text-align:center; margin-bottom: 20px">
This homeopathy web site is intended for information purposes only.
It is not suitable for self-medication or can replace the visit of a medical doctor/GP.
Scientifically, homeopathy was never proven to actually work!
The author of this web site does not take responsibility for the correctness of this sites'
The author of this web site does not take responsibility for the correctness of this site's
results or the consequences of misusing them.
</p>
</div>
Expand All @@ -41,7 +41,7 @@ <h4 style="text-align:center; margin-bottom: 20px">
<br>
<div class="container" style="margin-top: 0.5cm; font-size:12px;">
<p>
Copyright &#169; 2020-2022 Andreas Bauer. All rights reserved.
Copyright &#169; 2020-2023 Andreas Bauer. All rights reserved.
</p>
</div>
</div>
Expand Down
30 changes: 8 additions & 22 deletions backend/conf/application.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,6 @@ play.filters.enabled += "play.filters.csrf.CSRFFilter"
play.filters.csrf.cookie.name = "csrfCookie"
play.filters.csrf.token.name = "csrfToken"

# ############################################################################
# Not needed if reverse proxy (which uses https) is active:
#
# Redirect to https always
# play.filters.enabled += play.filters.https.RedirectHttpsFilter
# By default, the redirect only happens in Prod mode. To override this, set
# play.filters.https.redirectEnabled = true
#
# play.server.https.keyStore.path = ${OOREP_KEYSTORE_FILE}
# play.server.https.keyStore.type = "JKS"
# play.server.https.keyStore.password = ${OOREP_KEYSTORE_PASS}

# ############################################################################

# This effectively means that Csrf-Token is only sent via https, if set to true.
# (We don't need this due to Play acting behind reverse proxy. In fact, having
# it set to false means we can more easily test the Play application via http.)
Expand All @@ -34,8 +20,8 @@ play.filters.csrf.cookie.secure = false
play.http.session.secure = false

play.http.session.httpOnly = true
play.http.session.sameSite = "strict" # This is **crucial** against csrf attacks!
play.http.secret.key = ${OOREP_APPLICATION_SECRET} # https://www.playframework.com/documentation/2.7.x/ApplicationSecret
play.http.session.sameSite = "strict" # This is **crucial** against csrf attacks!
play.http.secret.key = ${OOREP_APP_SECRET} # https://www.playframework.com/documentation/2.7.x/ApplicationSecret

play.modules.enabled += "play.api.db.DBModule"
play.modules.enabled += "play.api.db.HikariCPModule"
Expand All @@ -45,7 +31,7 @@ play.http.parser.maxDiskBuffer=20MB

play.filters.hosts {
# Allow requests to example.com, its subdomains, and localhost:9000.
allowed = ["localhost", ".pspace.org", ".oorep.com"]
allowed = ["localhost", "."${?OOREP_APP_DOMAIN}]
}

play.db {
Expand All @@ -67,14 +53,14 @@ play.db {
}

db.default {
driver=org.postgresql.Driver
username = "oorep_user"
driver = org.postgresql.Driver
username = ${?OOREP_DB_USER}
password = ${?OOREP_DB_PASS}
database = "oorep"
database = ${?OOREP_DB_NAME}
host = ${?OOREP_DB_HOST}
portNumber = ${?OOREP_DB_PORT}
connectionTimeout = 30000
url = "jdbc:postgresql://"${?OOREP_DB_HOST}":"${OOREP_DB_PORT}"/oorep"
url = "jdbc:postgresql://"${?OOREP_DB_HOST}":"${OOREP_DB_PORT}"/"${?OOREP_DB_NAME}
}

play.evolutions.db.default.autoApply=true
play.evolutions.db.default.autoApply = true
1 change: 1 addition & 0 deletions backend/conf/routes
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ GET /favicon.ico controllers.Assets.at(path="/public/

GET /change_password org.multics.baueran.frep.backend.controllers.Get.changePassword(id: String)
GET /show org.multics.baueran.frep.backend.controllers.Get.show(repertory: String, symptom: String, page: Int, remedyString: String, minWeight: Int)
GET /show_mm org.multics.baueran.frep.backend.controllers.Get.showMM(materiaMedica: String, symptom: String, page: Int, hideSections: Boolean, remedyString: String)

GET / org.multics.baueran.frep.backend.controllers.Get.serve_static_html(page="index")
GET /:page org.multics.baueran.frep.backend.controllers.Get.serve_static_html(page:String)
Expand Down
Loading

0 comments on commit a832ec2

Please sign in to comment.