diff --git a/www/remark42/Makefile b/www/remark42/Makefile index 9da639cdc36b..8d32bcde2da9 100644 --- a/www/remark42/Makefile +++ b/www/remark42/Makefile @@ -1,128 +1,125 @@ PORTNAME= remark42 DISTVERSIONPREFIX= v DISTVERSION= 1.17.1 +PORTREVISION= 1 CATEGORIES= www MASTER_SITES= LOCAL/delphij:npmcache DISTFILES= ${PORTNAME}-npm-cache-${DISTVERSION}${EXTRACT_SUFX}:npmcache MAINTAINER= delphij@FreeBSD.org COMMENT= Privacy-focused lightweight commenting engine WWW= https://remark42.com/ LICENSE= MIT LICENSE_FILE= ${WRKSRC}/LICENSE BUILD_DEPENDS+= npm-node24>0:www/npm-node24 USES= cpe go:1.27,modules tar:xz GO_BUILDFLAGS= -ldflags "-s -w -X main.revision=${DISTVERSION}" GO_TARGET= app:${PREFIX}/libexec/${PORTNAME} GO_PKGNAME= github.com/${GH_ACCOUNT}/${PORTNAME}/backend LD_FLAG_X_PREFIX= -X ${GO_PKGNAME}/version MAKE_ENV+= npm_config_offline=true \ COREPACK_ENABLE_STRICT=0 USE_RC_SUBR= ${PORTNAME} USE_GITHUB= yes GH_ACCOUNT= umputun PLIST_FILES= libexec/${PORTNAME} GH_TUPLE= \ Depado:bfchroma:v2.0.0:depado_bfchroma_v2/vendor/github.com/Depado/bfchroma/v2 \ PuerkitoBio:goquery:v1.13.0:puerkitobio_goquery/vendor/github.com/PuerkitoBio/goquery \ alecthomas:chroma:v2.27.0:alecthomas_chroma_v2/vendor/github.com/alecthomas/chroma/v2 \ andybalholm:cascadia:v1.3.4:andybalholm_cascadia/vendor/github.com/andybalholm/cascadia \ aymerick:douceur:v0.2.0:aymerick_douceur/vendor/github.com/aymerick/douceur \ cespare:xxhash:v2.3.0:cespare_xxhash_v2/vendor/github.com/cespare/xxhash/v2 \ dghubble:oauth1:v0.7.3:dghubble_oauth1/vendor/github.com/dghubble/oauth1 \ didip:tollbooth:v8.0.1:didip_tollbooth_v8/vendor/github.com/didip/tollbooth/v8 \ dlclark:regexp2:v2.7.1:dlclark_regexp2_v2/vendor/github.com/dlclark/regexp2/v2 \ etcd-io:bbolt:v1.5.0:etcd_io_bbolt/vendor/go.etcd.io/bbolt \ go-oauth2:oauth2:v4.5.4:go_oauth2_oauth2_v4/vendor/github.com/go-oauth2/oauth2/v4 \ go-pkgz:auth:v2.3.0:go_pkgz_auth_v2/vendor/github.com/go-pkgz/auth \ go-pkgz:email:v0.8.0:go_pkgz_email/vendor/github.com/go-pkgz/email \ go-pkgz:expirable-cache:v3.1.1:go_pkgz_expirable_cache_v3/vendor/github.com/go-pkgz/expirable-cache \ go-pkgz:jrpc:v0.4.2:go_pkgz_jrpc/vendor/github.com/go-pkgz/jrpc \ go-pkgz:lcw:v2.1.0:go_pkgz_lcw_v2/vendor/github.com/go-pkgz/lcw \ go-pkgz:lgr:v0.12.4:go_pkgz_lgr/vendor/github.com/go-pkgz/lgr \ go-pkgz:notify:v1.5.0:go_pkgz_notify/vendor/github.com/go-pkgz/notify \ go-pkgz:repeater:v2.2.0:go_pkgz_repeater_v2/vendor/github.com/go-pkgz/repeater/v2 \ go-pkgz:rest:v1.24.0:go_pkgz_rest/vendor/github.com/go-pkgz/rest \ go-pkgz:routegroup:v1.6.1:go_pkgz_routegroup/vendor/github.com/go-pkgz/routegroup \ go-pkgz:syncs:v1.3.3:go_pkgz_syncs/vendor/github.com/go-pkgz/syncs \ golang-jwt:jwt:v5.3.1:golang_jwt_jwt_v5/vendor/github.com/golang-jwt/jwt/v5 \ golang:crypto:v0.56.0:golang_crypto/vendor/golang.org/x/crypto \ golang:image:v0.45.0:golang_image/vendor/golang.org/x/image \ golang:net:v0.58.0:golang_net/vendor/golang.org/x/net \ golang:oauth2:v0.36.0:golang_oauth2/vendor/golang.org/x/oauth2 \ golang:snappy:v1.0.0:golang_snappy/vendor/github.com/golang/snappy \ golang:sync:v0.22.0:golang_sync/vendor/golang.org/x/sync \ golang:sys:v0.47.0:golang_sys/vendor/golang.org/x/sys \ golang:text:v0.41.0:golang_text/vendor/golang.org/x/text \ google:uuid:v1.6.0:google_uuid/vendor/github.com/google/uuid \ googleapis:google-cloud-go:v0.9.0:googleapis_google_cloud_go/vendor/cloud.google.com/go/compute/metadata \ gorilla:css:v1.0.1:gorilla_css/vendor/github.com/gorilla/css \ gorilla:feeds:v1.2.0:gorilla_feeds/vendor/github.com/gorilla/feeds \ gorilla:websocket:v1.5.3:gorilla_websocket/vendor/github.com/gorilla/websocket \ hashicorp:golang-lru:v2.0.7:hashicorp_golang_lru_v2/vendor/github.com/hashicorp/golang-lru/v2 \ jessevdk:go-flags:v1.6.1:jessevdk_go_flags/vendor/github.com/jessevdk/go-flags \ klauspost:compress:v1.19.2:klauspost_compress/vendor/github.com/klauspost/compress \ kyokomi:emoji:v2.2.14:kyokomi_emoji_v2/vendor/github.com/kyokomi/emoji/v2 \ microcosm-cc:bluemonday:v1.0.27:microcosm_cc_bluemonday/vendor/github.com/microcosm-cc/bluemonday \ mongodb:mongo-go-driver:v1.17.9:mongodb_mongo_go_driver/vendor/go.mongodb.org/mongo-driver \ montanaflynn:stats:v0.12.4:montanaflynn_stats/vendor/github.com/montanaflynn/stats \ redis:go-redis:v9.22.0:redis_go_redis_v9/vendor/github.com/redis/go-redis/v9 \ rrivera:identicon:d5ba35832c0d:rrivera_identicon/vendor/github.com/rrivera/identicon \ rs:xid:v1.6.0:rs_xid/vendor/github.com/rs/xid \ russross:blackfriday:v2.1.0:russross_blackfriday_v2/vendor/github.com/russross/blackfriday/v2 \ skip2:go-qrcode:da1b6568686e:skip2_go_qrcode/vendor/github.com/skip2/go-qrcode \ slack-go:slack:v0.29.0:slack_go_slack/vendor/github.com/slack-go/slack \ stretchr:testify:v1.12.1:stretchr_testify/vendor/github.com/stretchr/testify \ uber-go:atomic:v1.11.0:uber_go_atomic/vendor/go.uber.org/atomic \ uber-go:goleak:v1.3.0:uber_go_goleak/vendor/go.uber.org/goleak \ xdg-go:pbkdf2:v1.0.0:xdg_go_pbkdf2/vendor/github.com/xdg-go/pbkdf2 \ xdg-go:scram:v1.2.0:xdg_go_scram/vendor/github.com/xdg-go/scram \ xdg-go:stringprep:v1.0.4:xdg_go_stringprep/vendor/github.com/xdg-go/stringprep \ yaml:go-yaml:v3.0.5:yaml_go_yaml/vendor/go.yaml.in/yaml/v3 \ youmark:pkcs8:a2c0da244d78:youmark_pkcs8/vendor/github.com/youmark/pkcs8 REMARK_PIDDIR= /var/run/${PORTNAME}/ REMARK_USER?= www REMARK_DATADIR?=/var/db/${PORTNAME} -REMARK_URL?= http://127.0.0.1:8080 - USE_RC_SUBR= remark SUB_LIST+= REMARK_PIDDIR=${REMARK_PIDDIR} \ REMARK_USER=${REMARK_USER} \ REMARK_DATADIR=${REMARK_DATADIR} # (for maintainer) helper target to generate node_modules tarball make-npm-cache: extract @cd ${WRKDIR} && ${RM} -r .npm @cd ${WRKSRC}/frontend/apps/${PORTNAME} \ && ${SETENV} HOME=${WRKDIR} COREPACK_ENABLE_STRICT=0 npm install --force @cd ${WRKDIR} \ && ${TAR} -cf - --mtime='1970-01-01 00:00Z' --owner=0 --group=0 --numeric-owner ${PORTNAME}-npm-cache-${DISTVERSION}${EXTRACT_SUFX} .npm \ ${PORTNAME}-${DISTVERSION}/frontend/apps/remark42/package-lock.json | \ ${XZ_CMD} -v9e > ${PORTNAME}-npm-cache-${DISTVERSION}${EXTRACT_SUFX} \ && ${ECHO} "Please upload the file ${WRKDIR}/${PORTNAME}-npm-cache-${DISTVERSION}${EXTRACT_SUFX}" pre-build: cd ${WRKSRC}/frontend/apps/${PORTNAME} && ${SETENV} HOME=${WRKDIR} npm install --force --legacy-peer-deps cd ${WRKSRC}/frontend/apps/${PORTNAME} && ${SETENV} HOME=${WRKDIR} npm run build ${RM} -r ${WRKSRC}/backend/app/cmd/web/ ${MV} ${WRKSRC}/frontend/apps/remark42/public ${WRKSRC}/backend/app/cmd/web - ${FIND} ${WRKSRC}/backend/app/cmd/web -type f \( -name '*.html' -or -name '*.js' -or -name '*.mjs' \) \ - -print -exec ${REINPLACE_CMD} -e "s|{% REMARK_URL %}|${REMARK_URL}|g" {} + do-build: cd ${WRKSRC}/backend && ${SETENV} ${MAKE_ENV} ${GO_ENV} GOPROXY=off ${GO_CMD} build ${GO_BUILDFLAGS} \ -o ${GO_WRKDIR_BIN}/${PORTNAME} ./app .include diff --git a/www/remark42/files/remark.in b/www/remark42/files/remark.in index caf4ccfdb555..74257b7450f6 100644 --- a/www/remark42/files/remark.in +++ b/www/remark42/files/remark.in @@ -1,305 +1,308 @@ #!/bin/sh # PROVIDE: remark # REQUIRE: LOGIN # KEYWORD: shutdown # Add the following lines to /etc/rc.conf to enable remark # remark_enable="YES" # # Required settings: # remark_enable (bool): Set to YES to enable remark # Default: NO # remark_url (str): URL to Remark42 server, required # # Options: # remark_secret (str): 256-bit shared key used to sign JWT. # Default: random string # remark_site (str): site name(s), multi # Default: remark # remark_store_type (str): type of storage, bolt or rpc # Default: bolt # remark_store_bolt_path (str): parent directory for the bolt files # Default: %%REMARK_DATADIR%% # remark_backup_path (str): backups location # Default: %%REMARK_DATADIR%%/backup # remark_avatar_fs_path (str): avatars location for fs store # Default: %%REMARK_DATADIR%%/avatars # remark_avatar_bolt_file (str): # avatars bolt file location # Default: %%REMARK_DATADIR%%/avatars.db # remark_avatar_uri (str): avatars store URI # Default: %%REMARK_DATADIR%%/avatars # remark_image_fs_path (str): permanent location of images # Default: %%REMARK_DATADIR%%/pictures # remark_image_fs_staging (str): # staging location of images # Default: %%REMARK_DATADIR%%/pictures.staging # remark_image_bolt_file (str): images bolt file location # Default: %%REMARK_DATADIR%%/pictures.db +# remark_remark_web_root (str): directory overriding the embedded frontend, +# e.g. %%WWWDIR%% (not created by the package) +# Default: unset (use the embedded frontend) # # Additional configuration variables available at https://remark42.com/docs/configuration/parameters/ # are exposed with similar naming convention. . /etc/rc.subr name=remark rcvar=remark_enable load_rc_config ${name} : ${remark_enable:="NO"} : ${remark_secret:="$(head -c32 /dev/urandom| uuencode -r -m -)"} : ${remark_url:=""} : ${remark_site:="remark"} : ${remark_store_type:="bolt"} : ${remark_store_bolt_path:="%%REMARK_DATADIR%%"} : ${remark_store_bolt_timeout:="30s"} : ${remark_store_rpc_api:=""} : ${remark_store_rpc_timeout:=""} : ${remark_store_rpc_auth_user:=""} : ${remark_store_rpc_auth_passwd:=""} : ${remark_admin_type:="shared"} : ${remark_admin_rpc_api:=""} : ${remark_admin_rpc_timeout:="5s"} : ${remark_admin_rpc_auth_user:=""} : ${remark_admin_rpc_auth_passwd:=""} : ${remark_admin_rpc_secret_per_site:=""} : ${remark_admin_shared_id:=""} : ${remark_admin_shared_email:=""} : ${remark_backup_path:="%%REMARK_DATADIR%%/backup"} : ${remark_backup_max:="10"} : ${remark_cache_type:="mem"} : ${remark_cache_redis_addr:=""} : ${remark_cache_max_items:=""} : ${remark_cache_max_value:=""} : ${remark_cache_max_size:=""} : ${remark_avatar_type:="fs"} : ${remark_avatar_fs_path:="%%REMARK_DATADIR%%/avatars"} : ${remark_avatar_bolt_file:="%%REMARK_DATADIR%%/avatars.db"} : ${remark_avatar_uri:=""} : ${remark_avatar_resize_limit:="0"} : ${remark_image_type:="fs"} : ${remark_image_fs_path:="%%REMARK_DATADIR%%/pictures"} : ${remark_image_fs_staging:="%%REMARK_DATADIR%%/pictures.staging"} : ${remark_image_fs_partitions:="100"} : ${remark_image_bolt_file:="%%REMARK_DATADIR%%/pictures.db"} : ${remark_image_rpc_api:=""} : ${remark_image_rpc_timeout:="5s"} : ${remark_image_rpc_auth_user:=""} : ${remark_image_rpc_auth_passwd:=""} : ${remark_image_max_size:="5000000"} : ${remark_image_resize_width:="2400"} : ${remark_image_resize_height:="900"} : ${remark_auth_same_site:="default"} : ${remark_auth_apple_cid:=""} : ${remark_auth_apple_tid:=""} : ${remark_auth_apple_kid:=""} : ${remark_auth_apple_private_key_filepath:=""} : ${remark_auth_google_cid:=""} : ${remark_auth_google_csec:=""} : ${remark_auth_facebook_cid:=""} : ${remark_auth_facebook_csec:=""} : ${remark_auth_microsoft_cid:=""} : ${remark_auth_microsoft_csec:=""} : ${remark_auth_github_cid:=""} : ${remark_auth_github_csec:=""} : ${remark_auth_twitter_cid:=""} : ${remark_auth_twitter_csec:=""} : ${remark_auth_patreon_cid:=""} : ${remark_auth_patreon_csec:=""} : ${remark_auth_discord_cid:=""} : ${remark_auth_discord_csec:=""} : ${remark_auth_yandex_cid:=""} : ${remark_auth_yandex_csec:=""} : ${remark_auth_telegram:=""} : ${remark_user:="%%REMARK_USER%%"} : ${remark_auth_anon:="false"} : ${remark_auth_enable:="false"} : ${remark_auth_email_from:=""} : ${remark_auth_email_subject:="remark42 confirmation"} : ${remark_auth_email_content_type:="text/html"} : ${remark_notify_users:=""} : ${remark_notify_admins:=""} : ${remark_notify_queue:=""} : ${remark_notify_telegram_chan:=""} : ${remark_notify_slack_token:=""} : ${remark_notify_slack_chan:=""} : ${remark_notify_webhook_url:=""} : ${remark_notify_webhook_template:=""} : ${remark_notify_webhook_headers:=""} : ${remark_notify_webhook_timeout:=""} : ${remark_notify_email_from:=""} : ${remark_notify_email_verification_subj:=""} : ${remark_telegram_token:=""} : ${remark_telegram_timeout:=""} : ${remark_smtp_host:=""} : ${remark_smtp_insecure_skip_verify:=""} : ${remark_smtp_port:=""} : ${remark_smtp_username:=""} : ${remark_smtp_password:=""} : ${remark_smtp_login_auth:=""} : ${remark_smtp_tls:=""} : ${remark_smtp_starttls:=""} : ${remark_smtp_timeout:=""} : ${remark_ssl_type:=""} : ${remark_ssl_port:=""} : ${remark_ssl_cert:=""} : ${remark_ssl_key:=""} : ${remark_ssl_acme_location:=""} : ${remark_ssl_acme_email:=""} : ${remark_max_comment_size:=""} : ${remark_min_comment_size:=""} : ${remark_max_votes:=""} : ${remark_votes_ip:=""} : ${remark_anon_vote:=""} : ${remark_votes_ip_time:=""} : ${remark_low_score:=""} : ${remark_critical_score:=""} : ${remark_positive_score:=""} : ${remark_restricted_words:=""} : ${remark_restricted_names:=""} : ${remark_edit_time:=""} : ${remark_admin_edit:=""} : ${remark_readonly_age:=""} : ${remark_image_proxy_http2https:=""} : ${remark_image_proxy_cache_external:=""} : ${remark_emoji:=""} : ${remark_simple_view:=""} : ${remark_proxy_cors:=""} : ${remark_allowed_hosts:=""} : ${remark_remark_address:=""} : ${remark_remark_port:=""} : ${remark_remark_web_root:=""} : ${remark_update_limit:=""} : ${remark_subscribers_only:=""} : ${remark_disable_fancy_html_formatting:=""} : ${remark_disable_signature:=""} : ${remark_admin_passwd:=""} : ${remark_debug:=""} export_variable() { _var="remark_$(echo $1 | tr A-Z a-z)" eval _val="\$${_var}" [ -z "${_val}" ] || export "${1}"="${_val}" } export_variables() { for _v in $@; do export_variable "${_v}" done } remark_precmd() { install -d -o ${remark_user} %%REMARK_PIDDIR%% install -d -o ${remark_user} ${remark_store_bolt_path} if [ -z "${remark_url}" ]; then err 1 "remark_url must be set" fi export REMARK_URL="${remark_url}" export REMARK_SITE="${remark_site}" export_variables SECRET SITE STORE_TYPE case "${STORE_TYPE}" in bolt) export_variables STORE_BOLT_PATH STORE_BOLT_TIMEOUT ;; rpc) export_variables STORE_RPC_API STORE_RPC_TIMEOUT STORE_RPC_AUTH_USER STORE_RPC_AUTH_PASSWD ;; *) err 1 "remark_store_type has to be either 'bolt' or 'rpc'" ;; esac export_variable ADMIN_TYPE case "${ADMIN_TYPE}" in shared) ;; rpc) export_variables ADMIN_RPC_API ADMIN_RPC_TIMEOUT ADMIN_RPC_AUTH_USER ADMIN_RPC_AUTH_PASSWD ;; *) err 1 "remark_admin_type has to be either 'shared' or 'rpc'" ;; esac export_variables ADMIN_SHARED_ID ADMIN_SHARED_EMAIL ADMIN_RPC_SECRET_PER_SITE BACKUP_PATH export MAX_BACKUP_FILES="${remark_backup_max}" export_variables CACHE_TYPE CACHE_REDIS_ADDR CACHE_MAX_ITEMS CACHE_MAX_VALUE CACHE_MAX_SIZE AVATAR_TYPE case "${AVATAR_TYPE}" in fs) export_variable AVATAR_FS_PATH ;; bolt) export_variable AVATAR_BOLT_FILE ;; uri) export_variable AVATAR_URI ;; *) err 1 "remark_avatar_path has to be 'fs', 'bolt' or 'uri'" ;; esac export AVATAR_RESIZE="${remark_avatar_resize_limit}" export_variable IMAGE_TYPE case "${remark_image_type}" in fs) export_variables IMAGE_FS_PATH IMAGE_FS_STAGING IMAGE_FS_PARTITIONS ;; bolt) export_variable IMAGE_BOLT_FILE ;; rpc) export_variables IMAGE_RPC_API IMAGE_RPC_TIMEOUT IMAGE_RPC_AUTH_USER IMAGE_RPC_AUTH_PASSWD ;; *) err 1 "remark_image_type has to be 'fs', 'bolt' or 'rpc'" ;; esac export_variables IMAGE_MAX_SIZE IMAGE_RESIZE_WIDTH IMAGE_RESIZE_HEIGHT AUTH_SAME_SITE AUTH_TELEGRAM # Export Apple auth separately due to different parameters export_variables AUTH_APPLE_CID AUTH_APPLE_TID AUTH_APPLE_KID AUTH_APPLE_PRIVATE_KEY_FILEPATH for _provider in google facebook microsoft github twitter patreon discord yandex; do _provider_upper="$(echo ${_provider} | tr a-z A-Z)" export_variables "AUTH_${_provider_upper}_CID" "AUTH_${_provider_upper}_CSEC" done export_variables AUTH_ANON AUTH_EMAIL_ENABLE AUTH_EMAIL_FROM AUTH_EMAIL_SUBJ AUTH_EMAIL_CONTENT_TYPE export_variables NOTIFY_USERS NOTIFY_ADMINS NOTIFY_QUEUE NOTIFY_TELEGRAM_CHAN NOTIFY_SLACK_TOKEN NOTIFY_SLACK_CHAN export_variables NOTIFY_WEBHOOK_URL NOTIFY_WEBHOOK_TEMPLATE NOTIFY_WEBHOOK_HEADERS NOTIFY_WEBHOOK_TIMEOUT export_variables NOTIFY_EMAIL_FROM NOTIFY_EMAIL_VERIFICATION_SUBJ TELEGRAM_TOKEN TELEGRAM_TIMEOUT export_variables SMTP_HOST SMTP_INSECURE_SKIP_VERIFY SMTP_PORT SMTP_USERNAME SMTP_PASSWORD SMTP_LOGIN_AUTH SMTP_TLS export_variables SMTP_STARTTLS SMTP_TIMEOUT SSL_TYPE SSL_PORT SSL_CERT SSL_KEY SSL_ACME_LOCATION export_variables SSL_ACME_EMAIL MAX_COMMENT_SIZE MIN_COMMENT_SIZE MAX_VOTES VOTES_IP ANON_VOTE VOTES_IP_TIME export_variables LOW_SCORE CRITICAL_SCORE POSITIVE_SCORE RESTRICTED_WORDS RESTRICTED_NAMES export_variables EDIT_TIME ADMIN_EDIT READONLY_AGE IMAGE_PROXY_HTTP2HTTPS IMAGE_PROXY_CACHE_EXTERNAL export_variables EMOJI SIMPLE_VIEW PROXY_CORS ALLOWED_HOSTS REMARK_ADDRESS REMARK_PORT REMARK_WEB_ROOT export_variables UPDATE_LIMIT SUBSCRIBERS_ONLY DISABLE_FANCY_HTML_FORMATTING DISABLE_SIGNATURE ADMIN_PASSWD DEBUG } pidfile="%%REMARK_PIDDIR%%${name}.pid" procname="%%PREFIX%%/libexec/remark42" command=/usr/sbin/daemon command_args="-c -p ${pidfile} -T ${name} ${procname} server ${remark_options}" start_precmd="remark_precmd" extra_commands="backup restore cleanup" cleanup_cmd="cleanup" cleanup_precmd="remark_precmd" backup_cmd="backup" backup_precmd="remark_precmd" restore_cmd="restore" restore_precmd="remark_precmd" cleanup() { su -m ${remark_user} -c "${procname} cleanup $@" } backup() { su -m ${remark_user} -c "${procname} backup $@" } restore() { su -m ${remark_user} -c "${procname} restore $@" } run_rc_command $@