Compare commits

..

27 Commits
dev ... auth0

Author SHA1 Message Date
86ca9f1ecb Add support for auth0 2023-01-24 19:55:16 -05:00
b9f008603a OCR fixes 2023-01-13 20:13:20 -05:00
a074d8cf10 cleanup/fixes 2022-12-19 19:05:35 -05:00
795b6e2e2e Merge pull request #321 from simon987/dependabot/npm_and_yarn/sist2-vue/express-4.18.2
Bump express from 4.17.1 to 4.18.2 in /sist2-vue
2022-12-19 18:33:55 -05:00
dependabot[bot]
59fd0f935c Bump express from 4.17.1 to 4.18.2 in /sist2-vue
Bumps [express](https://github.com/expressjs/express) from 4.17.1 to 4.18.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.17.1...4.18.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-14 19:55:36 +00:00
3bd1f593b0 Fix dockerfile 2022-12-03 18:00:55 -05:00
8e93d50d9e Merge pull request #320 from simon987/dependabot/npm_and_yarn/sist2-admin/frontend/loader-utils-1.4.2
Bump loader-utils from 1.4.0 to 1.4.2 in /sist2-admin/frontend
2022-12-03 17:11:48 -05:00
dependabot[bot]
e093a8a05c Bump loader-utils from 1.4.0 to 1.4.2 in /sist2-admin/frontend
Bumps [loader-utils](https://github.com/webpack/loader-utils) from 1.4.0 to 1.4.2.
- [Release notes](https://github.com/webpack/loader-utils/releases)
- [Changelog](https://github.com/webpack/loader-utils/blob/v1.4.2/CHANGELOG.md)
- [Commits](https://github.com/webpack/loader-utils/compare/v1.4.0...v1.4.2)

---
updated-dependencies:
- dependency-name: loader-utils
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-03 22:11:40 +00:00
588b4df164 Merge pull request #319 from simon987/dependabot/npm_and_yarn/sist2-admin/frontend/ejs-and-vue/cli-plugin-babel-and-vue/cli-plugin-eslint-and-vue/cli-plugin-router-and-vue/cli-plugin-vuex-and-vue/cli-service--removed
Bump ejs, @vue/cli-plugin-babel, @vue/cli-plugin-eslint, @vue/cli-plugin-router, @vue/cli-plugin-vuex and @vue/cli-service in /sist2-admin/frontend
2022-12-03 17:11:06 -05:00
dependabot[bot]
8b1740958b Bump ejs, @vue/cli-plugin-babel, @vue/cli-plugin-eslint, @vue/cli-plugin-router, @vue/cli-plugin-vuex and @vue/cli-service
Removes [ejs](https://github.com/mde/ejs). It's no longer used after updating ancestor dependencies [ejs](https://github.com/mde/ejs), [@vue/cli-plugin-babel](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-babel), [@vue/cli-plugin-eslint](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-eslint), [@vue/cli-plugin-router](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-router), [@vue/cli-plugin-vuex](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-plugin-vuex) and [@vue/cli-service](https://github.com/vuejs/vue-cli/tree/HEAD/packages/@vue/cli-service). These dependencies need to be updated together.


Removes `ejs`

Updates `@vue/cli-plugin-babel` from 4.5.17 to 5.0.8
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v5.0.8/packages/@vue/cli-plugin-babel)

Updates `@vue/cli-plugin-eslint` from 4.5.17 to 5.0.8
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v5.0.8/packages/@vue/cli-plugin-eslint)

Updates `@vue/cli-plugin-router` from 4.5.17 to 5.0.8
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v5.0.8/packages/@vue/cli-plugin-router)

Updates `@vue/cli-plugin-vuex` from 4.5.17 to 5.0.8
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v5.0.8/packages/@vue/cli-plugin-vuex)

Updates `@vue/cli-service` from 4.5.17 to 5.0.8
- [Release notes](https://github.com/vuejs/vue-cli/releases)
- [Changelog](https://github.com/vuejs/vue-cli/blob/dev/CHANGELOG.md)
- [Commits](https://github.com/vuejs/vue-cli/commits/v5.0.8/packages/@vue/cli-service)

---
updated-dependencies:
- dependency-name: ejs
  dependency-type: indirect
- dependency-name: "@vue/cli-plugin-babel"
  dependency-type: direct:development
- dependency-name: "@vue/cli-plugin-eslint"
  dependency-type: direct:development
- dependency-name: "@vue/cli-plugin-router"
  dependency-type: direct:development
- dependency-name: "@vue/cli-plugin-vuex"
  dependency-type: direct:development
- dependency-name: "@vue/cli-service"
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-03 22:10:39 +00:00
fe25ad5459 Merge pull request #317 from simon987/dependabot/npm_and_yarn/sist2-admin/frontend/eventsource-1.1.2
Bump eventsource from 1.1.0 to 1.1.2 in /sist2-admin/frontend
2022-12-03 17:09:12 -05:00
dependabot[bot]
83d9e0fb4b Bump eventsource from 1.1.0 to 1.1.2 in /sist2-admin/frontend
Bumps [eventsource](https://github.com/EventSource/eventsource) from 1.1.0 to 1.1.2.
- [Release notes](https://github.com/EventSource/eventsource/releases)
- [Changelog](https://github.com/EventSource/eventsource/blob/master/HISTORY.md)
- [Commits](https://github.com/EventSource/eventsource/compare/v1.1.0...v1.1.2)

---
updated-dependencies:
- dependency-name: eventsource
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-03 22:09:00 +00:00
6c8e6ac0b3 Merge pull request #313 from simon987/dependabot/npm_and_yarn/sist2-admin/frontend/decode-uri-component-0.2.2
Bump decode-uri-component from 0.2.0 to 0.2.2 in /sist2-admin/frontend
2022-12-03 17:07:57 -05:00
dependabot[bot]
2de2f87f16 Bump decode-uri-component from 0.2.0 to 0.2.2 in /sist2-admin/frontend
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-12-03 22:07:23 +00:00
61eb311577 Merge pull request #292 from simon987/dependabot/npm_and_yarn/sist2-vue/eventsource-1.1.1
Bump eventsource from 1.1.0 to 1.1.1 in /sist2-vue
2022-12-03 17:06:45 -05:00
f3a4598cfd Merge pull request #298 from simon987/dependabot/npm_and_yarn/sist2-vue/terser-4.8.1
Bump terser from 4.8.0 to 4.8.1 in /sist2-vue
2022-12-03 17:06:39 -05:00
e135efaa4b Merge pull request #303 from simon987/dependabot/npm_and_yarn/sist2-vue/d3-color-and-d3-3.1.0
Bump d3-color and d3 in /sist2-vue
2022-12-03 17:06:32 -05:00
5d488acd77 Merge pull request #310 from simon987/dependabot/npm_and_yarn/sist2-vue/minimatch-3.1.2
Bump minimatch from 3.0.4 to 3.1.2 in /sist2-vue
2022-12-03 17:06:26 -05:00
79b78a92f8 Merge pull request #312 from simon987/dev
v2.13.0
2022-12-03 17:06:19 -05:00
dependabot[bot]
1baf3861f7 Bump minimatch from 3.0.4 to 3.1.2 in /sist2-vue
Bumps [minimatch](https://github.com/isaacs/minimatch) from 3.0.4 to 3.1.2.
- [Release notes](https://github.com/isaacs/minimatch/releases)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.0.4...v3.1.2)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-11-12 14:27:07 +00:00
dependabot[bot]
25fb912f69 Bump d3-color and d3 in /sist2-vue
Bumps [d3-color](https://github.com/d3/d3-color) to 3.1.0 and updates ancestor dependency [d3](https://github.com/d3/d3). These dependencies need to be updated together.


Updates `d3-color` from 1.4.1 to 3.1.0
- [Release notes](https://github.com/d3/d3-color/releases)
- [Commits](https://github.com/d3/d3-color/compare/v1.4.1...v3.1.0)

Updates `d3` from 5.16.0 to 7.6.1
- [Release notes](https://github.com/d3/d3/releases)
- [Changelog](https://github.com/d3/d3/blob/main/CHANGES.md)
- [Commits](https://github.com/d3/d3/compare/v5.16.0...v7.6.1)

---
updated-dependencies:
- dependency-name: d3-color
  dependency-type: indirect
- dependency-name: d3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-09-30 00:54:51 +00:00
dependabot[bot]
e7f27cfd13 Bump terser from 4.8.0 to 4.8.1 in /sist2-vue
Bumps [terser](https://github.com/terser/terser) from 4.8.0 to 4.8.1.
- [Release notes](https://github.com/terser/terser/releases)
- [Changelog](https://github.com/terser/terser/blob/master/CHANGELOG.md)
- [Commits](https://github.com/terser/terser/commits)

---
updated-dependencies:
- dependency-name: terser
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-07-21 19:34:05 +00:00
dependabot[bot]
6e38653f2f Bump eventsource from 1.1.0 to 1.1.1 in /sist2-vue
Bumps [eventsource](https://github.com/EventSource/eventsource) from 1.1.0 to 1.1.1.
- [Release notes](https://github.com/EventSource/eventsource/releases)
- [Changelog](https://github.com/EventSource/eventsource/blob/master/HISTORY.md)
- [Commits](https://github.com/EventSource/eventsource/compare/v1.1.0...v1.1.1)

---
updated-dependencies:
- dependency-name: eventsource
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-06-01 22:27:52 +00:00
4e1109c528 Merge pull request #288 from simon987/dev
v2.12.1
2022-04-23 10:30:19 -04:00
a74726be55 Merge pull request #285 from simon987/dependabot/npm_and_yarn/sist2-vue/async-2.6.4
Bump async from 2.6.3 to 2.6.4 in /sist2-vue
2022-04-17 13:42:40 -04:00
dependabot[bot]
cb228052d2 Bump async from 2.6.3 to 2.6.4 in /sist2-vue
Bumps [async](https://github.com/caolan/async) from 2.6.3 to 2.6.4.
- [Release notes](https://github.com/caolan/async/releases)
- [Changelog](https://github.com/caolan/async/blob/v2.6.4/CHANGELOG.md)
- [Commits](https://github.com/caolan/async/compare/v2.6.3...v2.6.4)

---
updated-dependencies:
- dependency-name: async
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2022-04-17 17:41:14 +00:00
fe56da95d5 Merge pull request #284 from simon987/dev
v2.12.0
2022-04-17 13:38:42 -04:00
48 changed files with 19309 additions and 61079 deletions

View File

@@ -8,6 +8,7 @@ Testing/
**/cmake_install.cmake
**/CMakeCache.txt
**/CMakeFiles/
.cmake
LICENSE
Makefile
**/*.md

View File

@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.7)
set(CMAKE_C_STANDARD 11)
project(sist2 C)
project(sist2)
set(CMAKE_C_STANDARD 11)
option(SIST_DEBUG "Build a debug executable" on)
option(SIST_FAST "Enable more optimisation flags" off)
@@ -40,9 +40,12 @@ add_executable(sist2
src/stats.c src/stats.h src/ctx.c
src/parsing/sidecar.c src/parsing/sidecar.h
src/auth0/auth0_c_api.h src/auth0/auth0_c_api.cpp
# argparse
third-party/argparse/argparse.h third-party/argparse/argparse.c
)
set_target_properties(sist2 PROPERTIES LINKER_LANGUAGE C)
target_link_directories(sist2 PRIVATE BEFORE ${_VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/lib/)
set(CMAKE_FIND_LIBRARY_SUFFIXES .a .lib)

View File

@@ -14,17 +14,17 @@ RUN cmake -DSIST_PLATFORM=x64_linux -DSIST_DEBUG=off -DBUILD_TESTS=off -DCMAKE_T
RUN make -j$(nproc)
RUN strip sist2 || mv sist2_debug sist2
FROM --platform="linux/amd64" ubuntu:20.04
FROM --platform="linux/amd64" ubuntu@sha256:965fbcae990b0467ed5657caceaec165018ef44a4d2d46c7cdea80a9dff0d1ea
WORKDIR /root
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8
ENTRYPOINT ["sist2"]
ENTRYPOINT ["/root/sist2"]
RUN apt update && DEBIAN_FRONTEND=noninteractive apt install -y curl libasan5 libmagic1 python3 \
python3-pip git tesseract-ocr && rm -rf /var/lib/apt/lists/*
python3-pip git tesseract-ocr libpq-dev && rm -rf /var/lib/apt/lists/*
RUN mkdir -p /usr/share/tessdata && \
cd /usr/share/tessdata/ && \
@@ -33,10 +33,12 @@ RUN mkdir -p /usr/share/tessdata && \
curl -o /usr/share/tessdata/eng.traineddata https://raw.githubusercontent.com/tesseract-ocr/tessdata/master/eng.traineddata &&\
curl -o /usr/share/tessdata/fra.traineddata https://raw.githubusercontent.com/tesseract-ocr/tessdata/master/fra.traineddata &&\
curl -o /usr/share/tessdata/rus.traineddata https://raw.githubusercontent.com/tesseract-ocr/tessdata/master/rus.traineddata &&\
curl -o /usr/share/tessdata/spa.traineddata https://raw.githubusercontent.com/tesseract-ocr/tessdata/master/spa.traineddata
curl -o /usr/share/tessdata/osd.traineddata https://raw.githubusercontent.com/tesseract-ocr/tessdata/master/osd.traineddata &&\
curl -o /usr/share/tessdata/spa.traineddata https://raw.githubusercontent.com/tesseract-ocr/tessdata/master/spa.traineddata &&\
curl -o /usr/share/tessdata/chi_sim.traineddata https://raw.githubusercontent.com/tesseract-ocr/tessdata/master/chi_sim.traineddata
# sist2
COPY --from=build /build/sist2 sist2
COPY --from=build /build/sist2 /root/sist2
# sist2-admin
COPY sist2-admin/requirements.txt sist2-admin/

View File

@@ -7,7 +7,7 @@ RUN cmake -DSIST_PLATFORM=arm64_linux -DSIST_DEBUG=off -DBUILD_TESTS=off -DCMAKE
RUN make -j$(nproc)
RUN strip sist2
FROM --platform="linux/arm64/v8" ubuntu:21.10
FROM --platform="linux/arm64/v8" ubuntu:20.04
RUN apt update && apt install -y curl libasan5 && rm -rf /var/lib/apt/lists/*

View File

@@ -74,6 +74,10 @@ Web options
--es-index=<str> Elasticsearch index name. DEFAULT=sist2
--bind=<str> Listen on this address. DEFAULT=localhost:4090
--auth=<str> Basic auth in user:password format
--auth0-audience=<str> API audience/identifier
--auth0-domain=<str> Application domain
--auth0-client-id=<str> Application client ID
--auth0-public-key-file=<str> Path to Auth0 public key file extracted from <domain>/pem
--tag-auth=<str> Basic auth in user:password format for tagging
--tagline=<str> Tagline in navbar
--dev Serve html & js files from disk (for development)
@@ -268,6 +272,7 @@ sist2 index --print ./my_index/ | jq | less
* `--dev` Serve html & js files from disk (for development, used to modify frontend files without having to recompile)
* `--lang=<str>` Set the default web UI language (See #180 for a list of supported languages, default
is `en`). The user can change the language in the configuration page
* `--auth0-audience`, `--auth0-domain`, `--auth0-client-id`, `--auth0-public-key-file` See [Authentication with Auth0](auth0.md)
### Web examples

19
docs/auth0.md Normal file
View File

@@ -0,0 +1,19 @@
# Authentication with Auth0
1. Create a new Auth0 application (Single page app)
2. Create a new Auth0 API:
1. Choose `RS256` signing algorithm
2. Set identifier (audience) to `https://sist2`
3. Download the Auth0 certificate from https://<domain>.auth0.com/pem (you can find the domain Applications->Basic information)
4. Extract the public key from the certificate using `openssl x509 -pubkey -noout -in cert.pem > pubkey.txt`
5. Start the sist2 web server
Example options:
```bash
sist2 web \
--auth0-client-id XXX \
--auth0-audience https://sist2 \
--auth0-domain YYY.auth0.com \
--auth0-public-key-file /ZZZ/pubkey.txt
```

View File

@@ -1 +1 @@
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>sist2-admin</title><link href="css/app.0f0b676b.css" rel="preload" as="style"><link href="css/chunk-vendors.aa66c7e8.css" rel="preload" as="style"><link href="js/app.b34f501e.js" rel="preload" as="script"><link href="js/chunk-vendors.fad0ee6a.js" rel="preload" as="script"><link href="css/chunk-vendors.aa66c7e8.css" rel="stylesheet"><link href="css/app.0f0b676b.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but sist2-admin-vue doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.fad0ee6a.js"></script><script src="js/app.b34f501e.js"></script></body></html>
<!DOCTYPE html><html lang=""><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1"><link rel="icon" href="favicon.ico"><title>sist2-admin</title><link href="css/app.css" rel="preload" as="style"><link href="css/chunk-vendors.css" rel="preload" as="style"><link href="js/app.js" rel="preload" as="script"><link href="js/chunk-vendors.js" rel="preload" as="script"><link href="css/chunk-vendors.css" rel="stylesheet"><link href="css/app.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but sist2-admin-vue doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="js/chunk-vendors.js"></script><script src="js/app.js"></script></body></html>

File diff suppressed because one or more lines are too long

View File

@@ -341,5 +341,4 @@ var e="jan._feb._mrt._apr._mei_jun._jul._aug._sep._okt._nov._dec.".split("_"),a=
//! moment.js locale configuration
var e=t.defineLocale("x-pseudo",{months:"J~áñúá~rý_F~ébrú~árý_~Márc~h_Áp~ríl_~Máý_~Júñé~_Júl~ý_Áú~gúst~_Sép~témb~ér_Ó~ctób~ér_Ñ~óvém~bér_~Décé~mbér".split("_"),monthsShort:"J~áñ_~Féb_~Már_~Ápr_~Máý_~Júñ_~Júl_~Áúg_~Sép_~Óct_~Ñóv_~Déc".split("_"),monthsParseExact:!0,weekdays:"S~úñdá~ý_Mó~ñdáý~_Túé~sdáý~_Wéd~ñésd~áý_T~húrs~dáý_~Fríd~áý_S~átúr~dáý".split("_"),weekdaysShort:"S~úñ_~Móñ_~Túé_~Wéd_~Thú_~Frí_~Sát".split("_"),weekdaysMin:"S~ú_Mó~_Tú_~Wé_T~h_Fr~_Sá".split("_"),weekdaysParseExact:!0,longDateFormat:{LT:"HH:mm",L:"DD/MM/YYYY",LL:"D MMMM YYYY",LLL:"D MMMM YYYY HH:mm",LLLL:"dddd, D MMMM YYYY HH:mm"},calendar:{sameDay:"[T~ódá~ý át] LT",nextDay:"[T~ómó~rró~w át] LT",nextWeek:"dddd [át] LT",lastDay:"[Ý~ést~érdá~ý át] LT",lastWeek:"[L~ást] dddd [át] LT",sameElse:"L"},relativeTime:{future:"í~ñ %s",past:"%s á~gó",s:"á ~féw ~sécó~ñds",ss:"%d s~écóñ~ds",m:"á ~míñ~úté",mm:"%d m~íñú~tés",h:"á~ñ hó~úr",hh:"%d h~óúrs",d:"á ~dáý",dd:"%d d~áýs",M:"á ~móñ~th",MM:"%d m~óñt~hs",y:"á ~ýéár",yy:"%d ý~éárs"},dayOfMonthOrdinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(t){var e=t%10,a=1===~~(t%100/10)?"th":1===e?"st":2===e?"nd":3===e?"rd":"th";return t+a},week:{dow:1,doy:4}});return e}))},fdbf:function(t,e,a){var n=a("4930");t.exports=n&&!Symbol.sham&&"symbol"==typeof Symbol.iterator},ffff:function(t,e,a){(function(t,e){e(a("c1df"))})(0,(function(t){"use strict";
//! moment.js locale configuration
var e=t.defineLocale("se",{months:"ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu".split("_"),monthsShort:"ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov".split("_"),weekdays:"sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat".split("_"),weekdaysShort:"sotn_vuos_maŋ_gask_duor_bear_láv".split("_"),weekdaysMin:"s_v_m_g_d_b_L".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"MMMM D. [b.] YYYY",LLL:"MMMM D. [b.] YYYY [ti.] HH:mm",LLLL:"dddd, MMMM D. [b.] YYYY [ti.] HH:mm"},calendar:{sameDay:"[otne ti] LT",nextDay:"[ihttin ti] LT",nextWeek:"dddd [ti] LT",lastDay:"[ikte ti] LT",lastWeek:"[ovddit] dddd [ti] LT",sameElse:"L"},relativeTime:{future:"%s geažes",past:"maŋit %s",s:"moadde sekunddat",ss:"%d sekunddat",m:"okta minuhta",mm:"%d minuhtat",h:"okta diimmu",hh:"%d diimmut",d:"okta beaivi",dd:"%d beaivvit",M:"okta mánnu",MM:"%d mánut",y:"okta jahki",yy:"%d jagit"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return e}))}}]);
//# sourceMappingURL=chunk-vendors.fad0ee6a.js.map
var e=t.defineLocale("se",{months:"ođđajagemánnu_guovvamánnu_njukčamánnu_cuoŋománnu_miessemánnu_geassemánnu_suoidnemánnu_borgemánnu_čakčamánnu_golggotmánnu_skábmamánnu_juovlamánnu".split("_"),monthsShort:"ođđj_guov_njuk_cuo_mies_geas_suoi_borg_čakč_golg_skáb_juov".split("_"),weekdays:"sotnabeaivi_vuossárga_maŋŋebárga_gaskavahkku_duorastat_bearjadat_lávvardat".split("_"),weekdaysShort:"sotn_vuos_maŋ_gask_duor_bear_láv".split("_"),weekdaysMin:"s_v_m_g_d_b_L".split("_"),longDateFormat:{LT:"HH:mm",LTS:"HH:mm:ss",L:"DD.MM.YYYY",LL:"MMMM D. [b.] YYYY",LLL:"MMMM D. [b.] YYYY [ti.] HH:mm",LLLL:"dddd, MMMM D. [b.] YYYY [ti.] HH:mm"},calendar:{sameDay:"[otne ti] LT",nextDay:"[ihttin ti] LT",nextWeek:"dddd [ti] LT",lastDay:"[ikte ti] LT",lastWeek:"[ovddit] dddd [ti] LT",sameElse:"L"},relativeTime:{future:"%s geažes",past:"maŋit %s",s:"moadde sekunddat",ss:"%d sekunddat",m:"okta minuhta",mm:"%d minuhtat",h:"okta diimmu",hh:"%d diimmut",d:"okta beaivi",dd:"%d beaivvit",M:"okta mánnu",MM:"%d mánut",y:"okta jahki",yy:"%d jagit"},dayOfMonthOrdinalParse:/\d{1,2}\./,ordinal:"%d.",week:{dow:1,doy:4}});return e}))}}]);

File diff suppressed because it is too large Load Diff

View File

@@ -19,11 +19,11 @@
"vuex": "^3.4.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.13",
"@vue/cli-plugin-eslint": "~4.5.13",
"@vue/cli-plugin-router": "~4.5.13",
"@vue/cli-plugin-vuex": "~4.5.13",
"@vue/cli-service": "~4.5.13",
"@vue/cli-plugin-babel": "~5.0.8",
"@vue/cli-plugin-eslint": "~5.0.8",
"@vue/cli-plugin-router": "~5.0.8",
"@vue/cli-plugin-vuex": "~5.0.8",
"@vue/cli-service": "~5.0.8",
"babel-eslint": "^10.1.0",
"bootstrap": "^4.5.2",
"eslint": "^6.7.2",

View File

@@ -34,6 +34,22 @@
<label>{{ $t("webOptions.tagAuth") }}</label>
<b-form-input v-model="options.tag_auth" @change="update()"></b-form-input>
<br>
<h5>Auth0 options</h5>
<label>{{ $t("webOptions.auth0Audience") }}</label>
<b-form-input v-model="options.auth0_audience" @change="update()"></b-form-input>
<label>{{ $t("webOptions.auth0Domain") }}</label>
<b-form-input v-model="options.auth0_domain" @change="update()"></b-form-input>
<label>{{ $t("webOptions.auth0ClientId") }}</label>
<b-form-input v-model="options.auth0_client_id" @change="update()"></b-form-input>
<label>{{ $t("webOptions.auth0PublicKey") }}</label>
<b-textarea rows="10" v-model="options.auth0_public_key" @change="update()"></b-textarea>
</div>
</template>

View File

@@ -42,13 +42,12 @@ export default {
runJobConfirmationTitle: "Task queued",
runJobConfirmation: "Check the Tasks page to monitor the status.",
monitoring: "Monitoring",
enableMonitoring: "Enable monitoring",
extraQueryArgs: "Extra query arguments when launching from sist2-admin",
customUrl: "Custom URL when launching from sist2-admin",
selectJobs: "Select jobs",
webOptions: {
title: "Web options",
esUrl: "Elasticsearch URL",
esIndex: "Elasticsearch index name",
esInsecure: "Do not verify SSL connections to Elasticsearch.",

View File

@@ -33,10 +33,6 @@
{{ $t("autoStart") }}
</b-form-checkbox>
<b-form-checkbox v-model="frontend.enable_monitoring" @change="update()">
{{ $t("enableMonitoring") }}
</b-form-checkbox>
<label>{{ $t("extraQueryArgs") }}</label>
<b-form-input v-model="frontend.extra_query_args" @change="update()"></b-form-input>
@@ -52,7 +48,7 @@
<br/>
<h4>{{ $t("jobOptions.title") }}</h4>
<h4>{{ $t("webOptions.title") }}</h4>
<b-card>
<WebOptions :options="frontend.web_options" :frontend-name="$route.params.name" @change="update()"></WebOptions>
</b-card>

View File

@@ -1,3 +1,5 @@
module.exports = {
publicPath: ""
publicPath: "",
filenameHashing: false,
productionSourceMap: false,
};

File diff suppressed because it is too large Load Diff

View File

@@ -37,6 +37,11 @@ class WebOptions(BaseModel):
tagline: str = "Lightning-fast file system indexer and search tool"
dev: bool = False
lang: str = "en"
auth0_audience: str = None
auth0_domain: str = None
auth0_client_id: str = None
auth0_public_key: str = None
auth0_public_key_file: str = None
def __init__(self, **kwargs):
super().__init__(**kwargs)
@@ -45,6 +50,14 @@ class WebOptions(BaseModel):
args = ["web", f"--es-url={self.es_url}", f"--bind={self.bind}",
f"--tagline={self.tagline}", f"--lang={self.lang}"]
if self.auth0_audience:
args.append(f"--auth0-audience={self.auth0_audience}")
if self.auth0_domain:
args.append(f"--auth0-domain={self.auth0_domain}")
if self.auth0_client_id:
args.append(f"--auth0-client-id={self.auth0_client_id}")
if self.auth0_public_key_file:
args.append(f"--auth0-public-key-file={self.auth0_public_key_file}")
if self.es_insecure_ssl:
args.append(f"--es-insecure-ssl")
if self.auth:
@@ -251,7 +264,7 @@ class Sist2:
@staticmethod
def _consume_logs_stderr(logs_cb, proc):
pipe_wrapper = TextIOWrapper(proc.stderr, encoding="utf8")
pipe_wrapper = TextIOWrapper(proc.stderr, encoding="utf8", errors="ignore")
try:
for line in pipe_wrapper:
if line.strip() == "":
@@ -263,7 +276,7 @@ class Sist2:
@staticmethod
def _consume_logs_stdout(logs_cb, proc):
pipe_wrapper = TextIOWrapper(proc.stdout, encoding="utf8")
pipe_wrapper = TextIOWrapper(proc.stdout, encoding="utf8", errors="ignore")
try:
for line in pipe_wrapper:
if line.strip() == "":
@@ -283,6 +296,14 @@ class Sist2:
# pipe_wrapper.close()
def web(self, options: WebOptions, name: str):
if options.auth0_public_key:
with NamedTemporaryFile("w", prefix="sist2-admin", suffix=".txt", delete=False) as f:
f.write(options.auth0_public_key)
options.auth0_public_key_file = f.name
else:
options.auth0_public_key_file = None
args = [
self._bin_path,
*options.args()

View File

@@ -13,7 +13,6 @@ class Sist2Frontend(BaseModel):
running: bool = False
auto_start: bool = False
enable_monitoring: bool = True
extra_query_args: str = ""
custom_url: str = None

8
sist2-vue/dist/css/chunk-vendors.css vendored Normal file

File diff suppressed because one or more lines are too long

1
sist2-vue/dist/css/index.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,32 +1,3 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no'/>
<title>sist2</title>
<link href="js/chunk-vendors.js" rel="preload" as="script"><link href="js/index.js" rel="preload" as="script"></head>
<body>
<noscript>
<style>
body {
<!doctype html><html lang="en"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"/><title>sist2</title><script defer="defer" src="js/chunk-vendors.js"></script><script defer="defer" src="js/index.js"></script><link href="css/chunk-vendors.css" rel="stylesheet"><link href="css/index.css" rel="stylesheet"></head><body><noscript><style>body {
height: initial;
}
</style>
<div style="text-align: center; margin-top: 100px">
<strong>
We're sorry but sist2 doesn't work properly without JavaScript enabled.
Please enable it to continue.
</strong>
<br/>
<strong>
Nous sommes désolés mais sist2 ne fonctionne pas correctement
si JavaScript est activé.
Veuillez l'activer pour continuer.
</strong>
</div>
</noscript>
<div id="app"></div>
<script type="text/javascript" src="js/chunk-vendors.js"></script><script type="text/javascript" src="js/index.js"></script></body>
</html>
}</style><div style="text-align: center; margin-top: 100px"><strong>We're sorry but sist2 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong><br/><strong>Nous sommes désolés mais sist2 ne fonctionne pas correctement si JavaScript est activé. Veuillez l'activer pour continuer.</strong></div></noscript><div id="app"></div></body></html>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

22922
sist2-vue/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -7,14 +7,15 @@
"build": "vue-cli-service build --mode production"
},
"dependencies": {
"@auth0/auth0-spa-js": "^2.0.2",
"@egjs/vue-infinitegrid": "3.3.0",
"axios": "^0.25.0",
"bootstrap-vue": "^2.21.2",
"core-js": "^3.6.5",
"d3": "^5.16.0",
"d3": "^5.6.1",
"date-fns": "^2.21.3",
"dom-to-image": "^2.6.0",
"fslightbox-vue": "file:../../../mnt/Hatchery/main/projects/sist2/fslightbox-vue-pro-1.3.1.tgz",
"fslightbox-vue": "file:../../../../mnt/Hatchery/projects/sist2/fslightbox-vue-pro-1.3.1.tgz",
"nouislider": "^15.2.0",
"underscore": "^1.13.1",
"vue": "^2.6.12",
@@ -26,12 +27,12 @@
"vuex": "^3.4.0"
},
"devDependencies": {
"@babel/polyfill": "^7.11.5",
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-router": "~4.5.0",
"@vue/cli-plugin-typescript": "~4.5.0",
"@vue/cli-plugin-vuex": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"@babel/polyfill": "^7.12.1",
"@vue/cli-plugin-babel": "~5.0.8",
"@vue/cli-plugin-router": "~5.0.8",
"@vue/cli-plugin-typescript": "^5.0.8",
"@vue/cli-plugin-vuex": "~5.0.8",
"@vue/cli-service": "^5.0.8",
"@vue/test-utils": "^1.0.3",
"bootstrap": "^4.5.2",
"inspire-tree": "^4.3.1",

View File

@@ -1,19 +1,33 @@
<template>
<div id="app" :class="getClass()">
<div id="app" :class="getClass()" v-if="!authLoading">
<NavBar></NavBar>
<router-view v-if="!configLoading"/>
</div>
<div class="loading-page" v-else>
<div class="loading-spinners">
<b-spinner type="grow" variant="primary"></b-spinner>
<b-spinner type="grow" variant="primary"></b-spinner>
<b-spinner type="grow" variant="primary"></b-spinner>
</div>
<div class="loading-text">
Loading Chargement 装载
</div>
</div>
</template>
<script>
import NavBar from "@/components/NavBar";
import {mapGetters} from "vuex";
import {mapActions, mapGetters, mapMutations} from "vuex";
import Sist2Api from "@/Sist2Api";
import {setupAuth0} from "@/main";
export default {
components: {NavBar},
data() {
return {
configLoading: false
configLoading: false,
authLoading: true,
sist2InfoLoading: true
}
},
computed: {
@@ -30,9 +44,43 @@ export default {
this.configLoading = true;
window.setTimeout(() => this.configLoading = false, 10);
}
if (mutation.type === "setAuth0Token") {
this.authLoading = false;
}
});
Sist2Api.getSist2Info().then(data => {
if (data.auth0Enabled) {
this.authLoading = true;
setupAuth0(data.auth0Domain, data.auth0ClientId, data.auth0Audience)
this.$auth.$watch("loading", loading => {
if (loading === false) {
if (!this.$auth.isAuthenticated) {
this.$auth.loginWithRedirect();
return;
}
// Remove "code" param
window.history.replaceState({}, "", "/" + window.location.hash);
this.$store.dispatch("loadAuth0Token");
}
});
} else {
this.authLoading = false;
}
this.setSist2Info(data);
this.setIndices(data.indices)
});
},
methods: {
...mapActions(["setSist2Info",]),
...mapMutations(["setIndices",]),
getClass() {
return {
"theme-light": this.optTheme === "light",
@@ -314,4 +362,22 @@ mark {
.pointer {
cursor: pointer;
}
.loading-page {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
height: 100%;
gap: 15px
}
.loading-spinners {
display: flex;
gap: 10px;
}
.loading-text {
text-align: center;
}
</style>

View File

@@ -9,13 +9,15 @@
<span class="badge badge-pill version" v-if="$store && $store.state.sist2Info">
v{{ sist2Version() }}<span v-if="isDebug()">-dbg</span><span v-if="isLegacy() && !hideLegacy()">-<a
href="https://github.com/simon987/sist2/blob/master/docs/USAGE.md#elasticsearch" target="_blank">legacyES</a></span>
href="https://github.com/simon987/sist2/blob/master/docs/USAGE.md#elasticsearch"
target="_blank">legacyES</a></span>
</span>
<span v-if="$store && $store.state.sist2Info" class="tagline" v-html="tagline()"></span>
<b-button class="ml-auto" to="stats" variant="link">{{ $t("stats") }}</b-button>
<b-button to="config" variant="link">{{ $t("config") }}</b-button>
<b-button v-if="$auth && $auth.isAuthenticated" variant="link" @click="onLogoutClick()">logout</b-button>
</b-navbar>
</template>
@@ -40,6 +42,9 @@ export default {
},
hideLegacy() {
return this.$store.state.optHideLegacy;
},
onLogoutClick() {
this.$auth.logout();
}
}
}

View File

@@ -335,8 +335,8 @@ export default {
indexPicker: {
selectNone: "Sélectionner aucun",
selectAll: "Sélectionner tout",
selectedIndex: "indice sélectionné",
selectedIndices: "indices sélectionnés",
selectedIndex: "index sélectionné",
selectedIndices: "index sélectionnés",
},
},
"zh-CN": {

View File

@@ -3,16 +3,32 @@ import 'mutationobserver-shim'
import Vue from 'vue'
import './plugins/bootstrap-vue'
import App from './App.vue'
import router from './router'
import router, {setUseAuth0} from './router'
import store from './store'
import VueI18n from "vue-i18n";
import messages from "@/i18n/messages";
import { Auth0Plugin } from './plugins/auth0';
import VueRouter from "vue-router";
Vue.config.productionTip = false;
export function setupAuth0(domain, clientId, audience) {
setUseAuth0(true);
Vue.use(Auth0Plugin, {
domain,
clientId,
audience,
onRedirectCallback: appState => {}
});
}
Vue.prototype.$auth = null;
Vue.config.productionTip = false;
Vue.use(VueI18n);
Vue.use(VueRouter);

View File

@@ -0,0 +1,138 @@
import Vue from 'vue';
import {createAuth0Client} from '@auth0/auth0-spa-js';
/** Define a default action to perform after authentication */
const DEFAULT_REDIRECT_CALLBACK = () =>
window.history.replaceState({}, document.title, window.location.pathname);
let instance;
/** Returns the current instance of the SDK */
export const getInstance = () => instance;
/** Creates an instance of the Auth0 SDK. If one has already been created, it returns that instance */
export const useAuth0 = ({
domain, clientId, audience,
onRedirectCallback = DEFAULT_REDIRECT_CALLBACK,
redirectUri = window.location.origin,
}) => {
if (instance) return instance;
// The 'instance' is simply a Vue object
instance = new Vue({
data() {
return {
loading: true,
isAuthenticated: false,
user: {},
auth0Client: null,
popupOpen: false,
error: null
};
},
methods: {
/** Authenticates the user using a popup window */
async loginWithPopup(options, config) {
this.popupOpen = true;
try {
await this.auth0Client.loginWithPopup(options, config);
this.user = await this.auth0Client.getUser();
this.isAuthenticated = await this.auth0Client.isAuthenticated();
this.error = null;
} catch (e) {
this.error = e;
// eslint-disable-next-line
console.error(e);
} finally {
this.popupOpen = false;
}
this.user = await this.auth0Client.getUser();
this.isAuthenticated = true;
},
/** Handles the callback when logging in using a redirect */
async handleRedirectCallback() {
this.loading = true;
try {
await this.auth0Client.handleRedirectCallback();
this.user = await this.auth0Client.getUser();
this.isAuthenticated = true;
this.error = null;
} catch (e) {
this.error = e;
} finally {
this.loading = false;
}
},
/** Authenticates the user using the redirect method */
loginWithRedirect(o) {
return this.auth0Client.loginWithRedirect(o);
},
/** Returns all the claims present in the ID token */
getIdTokenClaims(o) {
return this.auth0Client.getIdTokenClaims(o);
},
/** Returns the access token. If the token is invalid or missing, a new one is retrieved */
getTokenSilently(o) {
return this.auth0Client.getTokenSilently(o);
},
/** Gets the access token using a popup window */
getTokenWithPopup(o) {
return this.auth0Client.getTokenWithPopup(o);
},
/** Logs the user out and removes their session on the authorization server */
logout() {
return this.auth0Client.logout({ logoutParams: { returnTo: window.location.origin } });
}
},
/** Use this lifecycle method to instantiate the SDK client */
async created() {
// Create a new instance of the SDK client using members of the given options object
this.auth0Client = await createAuth0Client({
domain: domain,
clientId: clientId,
authorizationParams: {
redirect_uri: redirectUri,
audience: audience,
}
});
try {
// If the user is returning to the app after authentication..
if (
window.location.search.includes('code=') &&
window.location.search.includes('state=')
) {
// handle the redirect and retrieve tokens
const {appState} = await this.auth0Client.handleRedirectCallback();
this.error = null;
// Notify subscribers that the redirect callback has happened, passing the appState
// (useful for retrieving any pre-authentication state)
onRedirectCallback(appState);
}
} catch (e) {
this.error = e;
} finally {
// Initialize our internal authentication state
this.isAuthenticated = await this.auth0Client.isAuthenticated();
this.user = await this.auth0Client.getUser();
this.loading = false;
}
}
});
return instance;
};
// Create a simple Vue plugin to expose the wrapper object throughout the application
export const Auth0Plugin = {
install(Vue, options) {
Vue.prototype.$auth = useAuth0(options);
}
};

View File

@@ -0,0 +1,28 @@
import {getInstance} from "@/plugins/auth0";
export const authGuard = (to, from, next) => {
const authService = getInstance();
const fn = () => {
// If the user is authenticated, continue with the route
if (authService.isAuthenticated) {
return next();
}
// Otherwise, log in
authService.loginWithRedirect({appState: {targetUrl: to.fullPath}});
};
// If loading has already finished, check our auth state using `fn()`
if (!authService.loading) {
return fn();
}
// Watch for the loading property to change before we check isAuthenticated
authService.$watch("loading", loading => {
if (loading === false) {
return fn();
}
});
};

View File

@@ -4,14 +4,29 @@ import StatsPage from "../views/StatsPage.vue"
import Configuration from "../views/Configuration.vue"
import SearchPage from "@/views/SearchPage.vue";
import FilePage from "@/views/FilePage.vue";
import {authGuard as auth0AuthGuard} from "@/router/auth0";
Vue.use(VueRouter)
let USE_AUTH0 = false
export function setUseAuth0(val) {
USE_AUTH0 = val;
}
const authGuard = (to, from, next) => {
if (USE_AUTH0) {
return auth0AuthGuard(to, from, next);
}
next();
}
const routes: Array<RouteConfig> = [
{
path: "/",
name: "SearchPage",
component: SearchPage
component: SearchPage,
beforeEnter: authGuard
},
{
path: "/stats",
@@ -34,7 +49,7 @@ const router = new VueRouter({
mode: "hash",
base: process.env.BASE_URL,
routes,
scrollBehavior (to, from, savedPosition) {
scrollBehavior(to, from, savedPosition) {
// return desired position
}
})

View File

@@ -3,6 +3,7 @@ import Vuex from "vuex"
import VueRouter, {Route} from "vue-router";
import {EsHit, EsResult, EsTag, Index, Tag} from "@/Sist2Api";
import {deserializeMimes, randomSeed, serializeMimes} from "@/util";
import {getInstance} from "@/plugins/auth0.js";
const CONF_VERSION = 2;
@@ -82,7 +83,9 @@ export default new Vuex.Store({
uiDetailsMimeAgg: null,
uiShowDetails: false,
uiMimeMap: [] as any[]
uiMimeMap: [] as any[],
auth0Token: null
},
mutations: {
setUiShowDetails: (state, val) => state.uiShowDetails = val,
@@ -188,6 +191,7 @@ export default new Vuex.Store({
busTnTouchStart: (doc_id) => {
// noop
},
setAuth0Token: (state, val) => state.auth0Token = val,
},
actions: {
setSist2Info: (store, val) => {
@@ -332,6 +336,14 @@ export default new Vuex.Store({
commit("setUiLightboxCaptions", []);
commit("setUiLightboxKey", 0);
commit("setUiDetailsMimeAgg", null);
},
async loadAuth0Token({commit}) {
const authService = getInstance();
const accessToken = await authService.getTokenSilently()
commit("setAuth0Token", accessToken);
document.cookie = `sist2-auth0=${accessToken};`;
}
},
modules: {},

View File

@@ -153,7 +153,7 @@ export default {
components: {LanguageIcon, GearIcon, DebugInfo, Preloader},
data() {
return {
loading: true,
loading: false,
configLoading: false,
langOptions: [
{value: "en", text: this.$t("lang.en")},
@@ -257,11 +257,6 @@ export default {
}
},
mounted() {
sist2.getSist2Info().then(data => {
this.setSist2Info(data);
this.loading = false;
});
this.$store.subscribe((mutation) => {
if (mutation.type.startsWith("setOpt")) {
this.$store.dispatch("updateConfiguration");

View File

@@ -107,13 +107,6 @@ export default Vue.extend({
},
mounted() {
if (this.$store.state.sist2Info === null) {
sist2.getSist2Info().then(data => {
this.$store.dispatch("setSist2Info", data);
this.$store.commit("setIndices", data.indices);
});
}
let query = null;
if (this.$route.query.byId) {
query = this.findById(this.$route.query.byId);

View File

@@ -130,25 +130,18 @@ export default Vue.extend({
});
});
this.setIndices(this.$store.getters["sist2Info"].indices)
this.getDateRange().then((range: { min: number, max: number }) => {
this.setDateBoundsMin(range.min);
this.setDateBoundsMax(range.max);
sist2.getSist2Info().then(data => {
this.setSist2Info(data);
this.setIndices(data.indices);
const doBlankSearch = !this.$store.state.optUpdateMimeMap;
const doBlankSearch = !this.$store.state.optUpdateMimeMap;
Sist2Api.getMimeTypes(Sist2Query.searchQuery(doBlankSearch)).then(({mimeMap}) => {
this.$store.commit("setUiMimeMap", mimeMap);
this.uiLoading = false;
this.search(true);
});
}).catch(() => {
this.showErrorToast();
Sist2Api.getMimeTypes(Sist2Query.searchQuery(doBlankSearch)).then(({mimeMap}) => {
this.$store.commit("setUiMimeMap", mimeMap);
this.uiLoading = false;
this.search(true);
});
});
},

48
src/auth0/auth0_c_api.cpp Normal file
View File

@@ -0,0 +1,48 @@
#include "auth0_c_api.h"
#include "jwt/jwt.hpp"
#include "iostream"
#include "cjson/cJSON.h"
int auth0_verify_jwt(const char *secret_str, const char *token, const char *audience) {
using namespace jwt::params;
jwt::jwt_object object;
try {
object = jwt::decode(
token,
algorithms({"RS256"}),
secret(secret_str),
verify(true)
);
} catch (const jwt::TokenExpiredError& e) {
return AUTH0_ERR_EXPIRED;
} catch (const jwt::SignatureFormatError& e) {
return AUTH0_ERR_SIG_FORMAT;
} catch (const jwt::DecodeError& e) {
return AUTH0_ERR_DECODE;
} catch (const jwt::VerificationError& e) {
return AUTH0_ERR_VERIFICATION;
}
std::stringstream buf;
buf << object.payload();
std::string json_payload_str = buf.str();
cJSON *payload = cJSON_Parse(json_payload_str.c_str());
bool audience_ok = false;
cJSON *aud;
cJSON_ArrayForEach(aud, cJSON_GetObjectItem(payload, "aud")) {
if (aud != nullptr && strcmp(aud->valuestring, audience) == 0) {
audience_ok = true;
}
}
cJSON_Delete(payload);
if (!audience_ok) {
return AUTH0_ERR_AUDIENCE;
}
return AUTH0_OK;
}

21
src/auth0/auth0_c_api.h Normal file
View File

@@ -0,0 +1,21 @@
#ifndef SIST2_AUTH0_C_API_H
#define SIST2_AUTH0_C_API_H
#include "stdlib.h"
#ifdef __cplusplus
#define EXTERNC extern "C"
#else
#define EXTERNC
#endif
#define AUTH0_OK (0)
#define AUTH0_ERR_EXPIRED (1)
#define AUTH0_ERR_SIG_FORMAT (2)
#define AUTH0_ERR_DECODE (3)
#define AUTH0_ERR_VERIFICATION (4)
#define AUTH0_ERR_AUDIENCE (5)
EXTERNC int auth0_verify_jwt(const char *secret, const char *token, const char* audience);
#endif

View File

@@ -501,6 +501,37 @@ int web_args_validate(web_args_t *args, int argc, const char **argv) {
args->tag_auth_enabled = FALSE;
}
if (args->auth0_public_key_path != NULL || args->auth0_audience != NULL || args->auth0_client_id ||
args->auth0_domain) {
if (args->auth0_public_key_path == NULL) {
fprintf(stderr, "Missing --auth0-public-key-file argument");
return 1;
}
if (args->auth0_audience == NULL) {
fprintf(stderr, "Missing --auth0-audience argument");
return 1;
}
if (args->auth0_client_id == NULL) {
fprintf(stderr, "Missing --auth0-client-id argument");
return 1;
}
if (args->auth0_domain == NULL) {
fprintf(stderr, "Missing --auth0-domain argument");
return 1;
}
}
if (args->auth0_public_key_path != NULL) {
if (load_external_file(args->auth0_public_key_path, &args->auth0_public_key) != 0) {
return 1;
}
args->auth0_enabled = TRUE;
} else {
args->auth0_enabled = FALSE;
}
args->index_count = argc - 1;
args->indices = argv + 1;

View File

@@ -77,6 +77,12 @@ typedef struct web_args {
char *lang;
char auth_user[256];
char auth_pass[256];
int auth0_enabled;
char *auth0_audience;
char *auth0_domain;
char *auth0_client_id;
char *auth0_public_key_path;
char *auth0_public_key;
int auth_enabled;
int tag_auth_enabled;
int index_count;

View File

@@ -105,6 +105,13 @@ typedef struct {
char *auth_pass;
int auth_enabled;
int tag_auth_enabled;
int auth0_enabled;
char *auth0_public_key;
char *auth0_audience;
char *auth0_domain;
char *auth0_client_id;
char *tagline;
struct index_t indices[256];
char lang[10];

View File

@@ -13,6 +13,7 @@
#include "web/serve.h"
#include "parsing/mime.h"
#include "parsing/parse.h"
#include "auth0/auth0_c_api.h"
#include <signal.h>
#include <unistd.h>
@@ -209,8 +210,10 @@ void initialize_scan_context(scan_args_t *args) {
ScanCtx.ebook_ctx.content_size = args->content_size;
ScanCtx.ebook_ctx.enable_tn = args->tn_count > 0;
ScanCtx.ebook_ctx.tn_size = args->tn_size;
ScanCtx.ebook_ctx.tesseract_lang = args->tesseract_lang;
ScanCtx.ebook_ctx.tesseract_path = args->tesseract_path;
if (args->ocr_ebooks) {
ScanCtx.ebook_ctx.tesseract_lang = args->tesseract_lang;
ScanCtx.ebook_ctx.tesseract_path = args->tesseract_path;
}
ScanCtx.ebook_ctx.log = _log;
ScanCtx.ebook_ctx.logf = _logf;
ScanCtx.ebook_ctx.store = _store;
@@ -560,6 +563,11 @@ void sist2_web(web_args_t *args) {
WebCtx.tag_auth_enabled = args->tag_auth_enabled;
WebCtx.tagline = args->tagline;
WebCtx.dev = args->dev;
WebCtx.auth0_enabled = args->auth0_enabled;
WebCtx.auth0_public_key = args->auth0_public_key;
WebCtx.auth0_client_id = args->auth0_client_id;
WebCtx.auth0_domain = args->auth0_domain;
WebCtx.auth0_audience = args->auth0_audience;
strcpy(WebCtx.lang, args->lang);
for (int i = 0; i < args->index_count; i++) {
@@ -709,6 +717,10 @@ int main(int argc, const char *argv[]) {
OPT_STRING(0, "es-index", &common_es_index, "Elasticsearch index name. DEFAULT=sist2"),
OPT_STRING(0, "bind", &web_args->listen_address, "Listen on this address. DEFAULT=localhost:4090"),
OPT_STRING(0, "auth", &web_args->credentials, "Basic auth in user:password format"),
OPT_STRING(0, "auth0-audience", &web_args->auth0_audience, "API audience/identifier"),
OPT_STRING(0, "auth0-domain", &web_args->auth0_domain, "Application domain"),
OPT_STRING(0, "auth0-client-id", &web_args->auth0_client_id, "Application client ID"),
OPT_STRING(0, "auth0-public-key-file", &web_args->auth0_public_key_path, "Path to Auth0 public key file extracted from <domain>/pem"),
OPT_STRING(0, "tag-auth", &web_args->tag_credentials, "Basic auth in user:password format for tagging"),
OPT_STRING(0, "tagline", &web_args->tagline, "Tagline in navbar"),
OPT_BOOLEAN(0, "dev", &web_args->dev, "Serve html & js files from disk (for development)"),

View File

@@ -49,7 +49,7 @@
#include <ctype.h>
#include "git_hash.h"
#define VERSION "2.13.0"
#define VERSION "2.13.1"
static const char *const Version = VERSION;
#ifndef SIST_PLATFORM

View File

@@ -5,6 +5,7 @@
#include "static_generated.c"
#include "src/index/elastic.h"
#include "src/index/web.h"
#include "src/auth0/auth0_c_api.h"
#include <src/ctx.h>
@@ -342,6 +343,14 @@ void index_info(struct mg_connection *nc) {
cJSON_AddStringToObject(json, "sist2Hash", Sist2CommitHash);
cJSON_AddStringToObject(json, "lang", WebCtx.lang);
cJSON_AddBoolToObject(json, "dev", WebCtx.dev);
cJSON_AddBoolToObject(json, "auth0Enabled", WebCtx.auth0_enabled);
if (WebCtx.auth0_enabled) {
cJSON_AddStringToObject(json, "auth0Domain", WebCtx.auth0_domain);
cJSON_AddStringToObject(json, "auth0ClientId", WebCtx.auth0_client_id);
cJSON_AddStringToObject(json, "auth0Audience", WebCtx.auth0_audience);
}
#ifdef SIST_DEBUG
cJSON_AddBoolToObject(json, "debug", TRUE);
#else
@@ -588,6 +597,42 @@ int validate_auth(struct mg_connection *nc, struct mg_http_message *hm) {
return TRUE;
}
int check_auth0(struct mg_http_message *hm) {
struct mg_str *cookie = mg_http_get_header(hm, "Cookie");
if (cookie == NULL) {
LOG_WARNING("serve.c", "Unauthorized request (no auth cookie)")
return FALSE;
}
struct mg_str token = mg_str("");
char *token_str = NULL;
token = mg_http_get_header_var(*cookie, mg_str("sist2-auth0"));
if (token.len == 0) {
LOG_WARNING("serve.c", "Unauthorized request (no auth cookie)")
return FALSE;
}
token_str = malloc(token.len + 1);
strncpy(token_str, token.ptr, token.len);
*(token_str + token.len) = '\0';
int res = auth0_verify_jwt(
WebCtx.auth0_public_key,
token_str,
WebCtx.auth0_audience
);
free(token_str);
if (res != AUTH0_OK) {
LOG_WARNINGF("serve.c", "Unauthorized request (JWT validation error: %d)", res);
return FALSE;
}
return TRUE;
}
static void ev_router(struct mg_connection *nc, int ev, void *ev_data, UNUSED(void *fn_data)) {
if (ev == MG_EV_HTTP_MSG) {
@@ -606,20 +651,34 @@ static void ev_router(struct mg_connection *nc, int ev, void *ev_data, UNUSED(vo
if (mg_http_match_uri(hm, "/")) {
search_index(nc, hm);
return;
} else if (mg_http_match_uri(hm, "/favicon.ico")) {
favicon(nc, hm);
return;
} else if (mg_http_match_uri(hm, "/css/index.css")) {
style(nc, hm);
return;
} else if (mg_http_match_uri(hm, "/css/chunk-vendors.css")) {
style_vendor(nc, hm);
return;
} else if (mg_http_match_uri(hm, "/js/index.js")) {
javascript(nc, hm);
return;
} else if (mg_http_match_uri(hm, "/js/chunk-vendors.js")) {
javascript_vendor(nc, hm);
} else if (mg_http_match_uri(hm, "/es")) {
search(nc, hm);
return;
} else if (mg_http_match_uri(hm, "/i")) {
index_info(nc);
return;
}
if (WebCtx.auth0_enabled && !check_auth0(hm)) {
mg_http_reply(nc, 403, HTTP_SERVER_HEADER HTTP_TEXT_TYPE_HEADER, "Unauthorized (auth0 error)");
return;
}
if (mg_http_match_uri(hm, "/es")) {
search(nc, hm);
} else if (mg_http_match_uri(hm, "/status")) {
status(nc);
} else if (mg_http_match_uri(hm, "/f/*")) {

File diff suppressed because one or more lines are too long

View File

@@ -446,7 +446,7 @@ int decode_frame_and_save_thumbnail(scan_media_ctx_t *ctx, AVFormatContext *pFor
return SAVE_THUMBNAIL_FAILED;
}
if (ctx->tesseract_lang != NULL && IS_VIDEO(pFormatCtx) && thumbnail_index == 0) {
if (ctx->tesseract_lang != NULL && thumbnail_index == 0) {
ocr_image(ctx, doc, decoder, frame_and_packet->frame);
}