commit ee8686bc83be55d95d5e9e185ca8808600fa31b8
parent c3a3374e45cf53bbe839ba31d843b1c921e049cc
Author: James Eversole <james@eversole.co>
Date: Tue, 27 Dec 2022 12:25:14 -0600
Bugfix on UI elements when no secret is found. Add copy secret button on successful retrieval. Include deployment information and updated example files.
Diffstat:
11 files changed, 91 insertions(+), 113 deletions(-)
diff --git a/Purr.cabal b/Purr.cabal
@@ -68,7 +68,7 @@ library
, wai-middleware-static >=0.5
default-language: Haskell2010
-executable Purr-exe
+executable Purr-musl
main-is: Main.hs
other-modules:
Paths_Purr
@@ -82,46 +82,7 @@ executable Purr-exe
GeneralizedNewtypeDeriving
OverloadedStrings
ScopedTypeVariables
- ghc-options: -threaded -rtsopts -with-rtsopts=-N
- build-depends:
- Purr
- , base >=4.7
- , base64-bytestring >=1.2.0.0
- , blaze-html >=0.9.1.0
- , bytestring >=0.10.12.1
- , containers >=0.6.4.1
- , crypto-simple >=0.1.0.0
- , dhall >=1.40 && <1.41.2
- , http-types >=0.12.3
- , iso8601-time >=0.1.5
- , mtl >=2.2.2
- , random >=1.2
- , scotty ==0.12
- , shakespeare >=2.0.20
- , split >=0.2.3.4
- , sqlite-simple >=0.4.18.0
- , text >=1.2.5.0
- , time >=1.9
- , wai-extra >=3.1.12.1
- , wai-middleware-static >=0.5
- default-language: Haskell2010
-
-test-suite Purr-test
- type: exitcode-stdio-1.0
- main-is: Spec.hs
- other-modules:
- Paths_Purr
- hs-source-dirs:
- test
- default-extensions:
- ConstraintKinds
- DeriveGeneric
- FlexibleContexts
- FlexibleInstances
- GeneralizedNewtypeDeriving
- OverloadedStrings
- ScopedTypeVariables
- ghc-options: -threaded -rtsopts -with-rtsopts=-N
+ ghc-options: -threaded -rtsopts -with-rtsopts=-N -static -optl-static -optl-pthread -fPIC
build-depends:
Purr
, base >=4.7
diff --git a/README b/README
@@ -4,6 +4,12 @@ purr
https://purr.eversole.co
a work-in-progress web application offering customizable password generation and time-limited sharing of secrets.
+TECH STACK
+
+- Haskell and Scotty backend
+- HTMX frontend
+- SQLite database
+
GOALS
- Generate sufficiently memorable but secure passwords for use with accounts that don't offer better authentication methods.
@@ -14,16 +20,28 @@ GOALS
WHY TRUST YOU?
-You shouldn't. This is free and open-source software which you can run on your own hardware. Instructions for deployment are coming SOON™.
+You shouldn't. This is free and open-source software which you can run on your own hardware.
-TECH STACK
+DEPLOYMENT
-- Haskell and Scotty backend
-- HTMX frontend
-- SQLite database
+purr is intended to run in a docker container.
+This repo's Stack project is configured to use a musl-based docker container for builds.
+Assuming your working directory is inside of this repository:
+
+1. Copy "examples/config.dhall" to ./config.dhall - configure this file appropriately.
+ - Use `openssl rand -hex 10` to generate an encryption key for "dbKey"
+2. Copy "examples/Dockerfile" to ./Dockerfile
+3. If using default database file location, run: `mkdir ./data; touch ./data/Purr.sqlite`
+4. Run `chmod +x build-docker`
+5. Run `./build-docker $IMAGE_NAME` to complete the initial Stack build and create the container
+6. Orchestrate the container as desired
+ - docker run -d -v "$(pwd -P)/data/Purr.sqlite:/app/data/Purr.sqlite" \
+ -v "$(pwd -P)/config.dhall:/app/config.dhall" \
+ -p 5195:3000 purr
+ |- An example docker-stack.yml is provided: `docker stack deploy -c docker-stack.yml purr`
DEVELOPMENT & SUPPORT
-Please send me an email for support.
+Please send me an email for support or to provide patches.
Copyright 2022 James Eversole (james@eversole.co)
diff --git a/build-docker b/build-docker
@@ -0,0 +1,12 @@
+#!/bin/bash
+set -e
+# Date: 12/27/2022
+# Author: James Eversole
+# ISC License
+# This script completes a stack build and then builds a docker image
+# containing Purr. The image name is the first argument to the script.
+
+IMAGE_NAME=${1:-"purr"}
+
+stack build --copy-bins
+docker build . -t $IMAGE_NAME
diff --git a/examples/Dockerfile b/examples/Dockerfile
@@ -1,11 +1,10 @@
-FROM haskell:9.0.2
+FROM alpine:3.17.0
WORKDIR /app
-ADD . /app
-
-RUN stack setup
-RUN stack build --copy-bins --local-bin-path ./
+ADD ./views /app/views
+ADD ./src /app/src
+ADD ./bin/Purr-musl /app/Purr-musl
EXPOSE 3000
-CMD ./Purr-exe
+ENTRYPOINT ["/app/Purr-musl"]
diff --git a/examples/docker-stack.yml b/examples/docker-stack.yml
@@ -1,9 +1,5 @@
version: '3.1'
-# Default Docker Stack/Compose configuration for Purr.
-# You will need to change all instances of "REPLACEME" with the appropriate details.
-# Additionally, you may want to update the host port definitions for each service.
-
services:
purr:
image: purr
@@ -13,6 +9,7 @@ services:
- webnet
volumes:
- ./data/Purr.sqlite:/app/data/Purr.sqlite
+ - ./config.dhall:/app/config.dhall
networks:
webnet:
diff --git a/package.yaml b/package.yaml
@@ -52,23 +52,31 @@ library:
source-dirs: src
executables:
- Purr-exe:
+ Purr-musl:
main: Main.hs
source-dirs: app
ghc-options:
- -threaded
- -rtsopts
- -with-rtsopts=-N
+ - -static
+ - -optl-static
+ - -optl-pthread
+ - -fPIC
dependencies:
- Purr
-tests:
- Purr-test:
- main: Spec.hs
- source-dirs: test
- ghc-options:
- - -threaded
- - -rtsopts
- - -with-rtsopts=-N
- dependencies:
- - Purr
+ #tests:
+ # Purr-test:
+ # main: Spec.hs
+ # source-dirs: test
+ # ghc-options:
+ # - -threaded
+ # - -rtsopts
+ # - -with-rtsopts=-N
+ # - -static
+ # - -optl-static
+ # - -optl-pthread
+ # - -fPIC
+ # dependencies:
+ # - Purr
diff --git a/stack.yaml b/stack.yaml
@@ -1,54 +1,23 @@
# This file was automatically generated by 'stack init'
#
-# Some commonly used options have been documented as comments in this file.
-# For advanced use and comprehensive documentation of the format, please see:
-# https://docs.haskellstack.org/en/stable/yaml_configuration/
-
-# Resolver to choose a 'specific' stackage snapshot or a compiler version.
-# A snapshot resolver dictates the compiler version and the set of packages
-# to be used for project dependencies. For example:
-#
-# resolver: lts-3.5
-# resolver: nightly-2015-09-21
-# resolver: ghc-7.10.2
-#
-# The location of a snapshot can be provided as a file or url. Stack assumes
-# a snapshot provided as a file might change, whereas a url resource does not.
-#
-# resolver: ./custom-snapshot.yaml
-# resolver: https://example.com/snapshots/2018-01-01.yaml
resolver:
url: https://raw.githubusercontent.com/commercialhaskell/stackage-snapshots/master/lts/19/13.yaml
# User packages to be built.
-# Various formats can be used as shown in the example below.
-#
-# packages:
-# - some-directory
-# - https://example.com/foo/bar/baz-0.0.2.tar.gz
-# subdirs:
-# - auto-update
-# - wai
packages:
- .
-# Dependency packages to be pulled from upstream that are not in the resolver.
-# These entries can reference officially published versions as well as
-# forks / in-progress versions pinned to a git hash. For example:
#
extra-deps:
- crypto-simple-0.1.0.0@sha256:5c0e1e04a814d903743d7543245951a91a46817230fdf478fadca57116805fc1,1502
-#ghc-options:
+docker:
+ enable: true
+ image: "utdemir/ghc-musl:v24-ghc902"
-# Override default flag values for local packages and extra-deps
-# flags: {}
-
-# Extra package databases containing global packages
-# extra-package-dbs: []
+local-bin-path:
+ ./bin
+#ghc-options:
-# Control whether we use the GHC we find on the path
-# system-ghc: true
-#
# Require a specific version of stack, using version ranges
# require-stack-version: -any # Default
# require-stack-version: ">=2.7"
@@ -56,10 +25,3 @@ extra-deps:
# Override the architecture used by stack, especially useful on Windows
# arch: i386
# arch: x86_64
-#
-# Extra directories used by stack for building
-# extra-include-dirs: [/path/to/dir]
-# extra-lib-dirs: [/path/to/dir]
-#
-# Allow a newer minor version of GHC than the snapshot specifies
-# compiler-check: newer-minor
diff --git a/views/cassius/style.cassius b/views/cassius/style.cassius
@@ -172,9 +172,17 @@ input[type=number]
box-shadow: 8px 8px 12px #ccc
.pwResult
+ margin: 0.25em 0 0.75em 0
font-size: 1.5em
color: #f0f6f0
+.pwResultCopy
+ width: 1px
+ overflow: hidden
+ display: inline-block
+ height: 1px
+ color: rgba(255,255,255,0)
+
.shareNew
padding: 0.5em 0.5em 0.5em 1.5em
background-color: #{colorTwo}
diff --git a/views/index.hamlet b/views/index.hamlet
@@ -5,6 +5,7 @@ $doctype 5
<title>purr
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://unpkg.com/htmx.org@1.7.0" integrity="sha384-EzBXYPt0/T6gxNp0nuPtLkmRpmDBbjg6WmCUZRLXBBwYYmwAUxzlSGej0ARHX0Bo" crossorigin="anonymous">
+ <script src="/copySecret.js" integrity="sha384-jB3mpB1WyAo8ToD7oWm/LjXBnEImM/8GB7tjExykwuNErwdPHa9mihHlVJRtV+bt">
<link rel="stylesheet" href="/style.css">
<body>
diff --git a/views/public/copySecret.js b/views/public/copySecret.js
@@ -0,0 +1,10 @@
+function copySecret(secret) {
+ var tempText = document.createElement('input');
+ tempText.style = 'position: absolute; left: -1000px; top: -1000px';
+ tempText.value = secret;
+ document.body.appendChild(tempText);
+ tempText.select();
+ document.execCommand('copy');
+ document.body.removeChild(tempText);
+ document.getElementById('copyButton').innerHTML = "- secret copied -";
+}
diff --git a/views/pw.hamlet b/views/pw.hamlet
@@ -2,5 +2,7 @@
$maybe pw <- password
<p .resLink>secret found at <a href="/pw/#{link}">/pw/#{link}</a>:
<h3 .pwResult>#{pw}
+ <button #copyButton .mainButton onclick="copySecret('#{pw}')">copy secret</button>
$nothing
- <h3 .pwResult>no secret found at <a href="/pw/#{link}">/pw/#{link}</a>
+ <p .resLink>no secret found at
+ <br /><a href="/pw/#{link}">/pw/#{link}</a>