Bugfix on UI elements when no secret is found. Add copy secret button on successful retrieval. Include deployment information and updated example files.
This commit is contained in:
parent
c3a3374e45
commit
ee8686bc83
43
Purr.cabal
43
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
|
||||
|
30
README
30
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)
|
||||
|
12
build-docker
Executable file
12
build-docker
Executable file
@ -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
|
@ -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"]
|
||||
|
@ -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:
|
||||
|
30
package.yaml
30
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
|
||||
|
50
stack.yaml
50
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
|
||||
|
||||
docker:
|
||||
enable: true
|
||||
image: "utdemir/ghc-musl:v24-ghc902"
|
||||
|
||||
local-bin-path:
|
||||
./bin
|
||||
#ghc-options:
|
||||
|
||||
# Override default flag values for local packages and extra-deps
|
||||
# flags: {}
|
||||
|
||||
# Extra package databases containing global packages
|
||||
# extra-package-dbs: []
|
||||
|
||||
# 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
|
||||
|
@ -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}
|
||||
|
@ -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>
|
||||
|
10
views/public/copySecret.js
Normal file
10
views/public/copySecret.js
Normal file
@ -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 -";
|
||||
}
|
@ -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>
|
||||
|
Loading…
x
Reference in New Issue
Block a user