mirror of
https://github.com/dillonkearns/elm-pages-v3-beta.git
synced 2024-11-28 06:05:31 +03:00
Remove more obsolete secrets code.
This commit is contained in:
parent
f82ae79e24
commit
f9c85dec80
@ -11,7 +11,6 @@ import Page exposing (Page, PageWithState, StaticPayload)
|
||||
import Pages.PageUrl exposing (PageUrl)
|
||||
import Pages.Url
|
||||
import Route
|
||||
import Secrets
|
||||
import Shared
|
||||
import View exposing (View)
|
||||
|
||||
|
@ -10,7 +10,6 @@ import MySession
|
||||
import Page exposing (Page, PageWithState, StaticPayload)
|
||||
import Pages.PageUrl exposing (PageUrl)
|
||||
import Pages.Url
|
||||
import Secrets
|
||||
import Server.Request as Request
|
||||
import Server.Response
|
||||
import Session
|
||||
|
@ -1,83 +0,0 @@
|
||||
module Pages.Secrets exposing (Value, map, succeed, with)
|
||||
|
||||
{-| Secrets are a secure way to use environment variables in your DataSource.Http requests. The actual environment
|
||||
variable value is used to perform DataSource.Http requests, while the masked value is the only thing that ends up in your
|
||||
built site. Let's go through what happens in a concrete example:
|
||||
|
||||
|
||||
## Example
|
||||
|
||||
Let's say you execute this from the shell:
|
||||
|
||||
```shell
|
||||
GITHUB_TOKEN=abcd1234 API_KEY=xyz789 elm-pages build
|
||||
```
|
||||
|
||||
And your DataSource.Http request in your Elm code looks like this:
|
||||
|
||||
import Pages.Secrets as Secrets
|
||||
import DataSource.Http
|
||||
|
||||
DataSource.Http.request
|
||||
(Secrets.succeed
|
||||
(\apiKey githubToken ->
|
||||
{ url = "https://api.github.com/repos/dillonkearns/elm-pages?apiKey=" ++ apiKey
|
||||
, method = "GET"
|
||||
, headers = [ ( "Authorization", "Bearer " ++ githubToken ) ]
|
||||
, body = DataSource.Http.emptyBody
|
||||
}
|
||||
)
|
||||
|> Secrets.with "API_KEY"
|
||||
|> Secrets.with "BEARER"
|
||||
)
|
||||
(Decode.succeed ())
|
||||
)
|
||||
|
||||
The following masked values are what will be visible in your production bundle if you inspect the code or the Network tab:
|
||||
|
||||
[GET]https://api.github.com/repos/dillonkearns/elm-pages?apiKey=<API_KEY>Authorization : Bearer <BEARER>
|
||||
|
||||
So the actual Secrets only exist for the duration of the build in order to perform the DataSource.Http requests, but they
|
||||
are replaced with `<SECRET_NAME>` once that step is done and your assets are bundled.
|
||||
|
||||
@docs Value, map, succeed, with
|
||||
|
||||
-}
|
||||
|
||||
import Secrets
|
||||
|
||||
|
||||
{-| Represents a Secure value from your environment variables. `Pages.Secrets.Value`s are much like `Json.Decode.Value`s
|
||||
in that you can take raw values, map them, and combine them with other values into any data structure.
|
||||
-}
|
||||
type alias Value value =
|
||||
Secrets.Value value
|
||||
|
||||
|
||||
{-| Hardcode a secret value. Or, this can be used to start a pipeline-style value with several different secrets (see
|
||||
the example at the top of this page).
|
||||
|
||||
Warning: a hardcoded value is not protected by masking! Make sure to to use `Secrets.with` to fetch sentitive values from environment variables.
|
||||
|
||||
import Pages.Secrets as Secrets
|
||||
|
||||
Secrets.succeed "hardcoded-secret"
|
||||
|
||||
-}
|
||||
succeed : value -> Value value
|
||||
succeed =
|
||||
Secrets.succeed
|
||||
|
||||
|
||||
{-| Map a Secret's raw value into an arbitrary type or value.
|
||||
-}
|
||||
map : (valueA -> valueB) -> Value valueA -> Value valueB
|
||||
map =
|
||||
Secrets.map
|
||||
|
||||
|
||||
{-| Allows you to chain together multiple secrets. See the top of this page for a full example.
|
||||
-}
|
||||
with : String -> Value (String -> value) -> Value value
|
||||
with =
|
||||
Secrets.with
|
111
src/Secrets.elm
111
src/Secrets.elm
@ -1,111 +0,0 @@
|
||||
module Secrets exposing
|
||||
( Value
|
||||
, lookup
|
||||
, map
|
||||
, maskedLookup
|
||||
, succeed
|
||||
, with
|
||||
)
|
||||
|
||||
import BuildError exposing (BuildError)
|
||||
import Fuzzy
|
||||
import SecretsDict exposing (SecretsDict)
|
||||
import TerminalText as Terminal
|
||||
|
||||
|
||||
type Value value
|
||||
= Value (SecretsDict -> Result (List BuildError) value)
|
||||
|
||||
|
||||
lookup : SecretsDict -> Value a -> Result (List BuildError) a
|
||||
lookup secrets (Value lookupSecrets) =
|
||||
lookupSecrets secrets
|
||||
|
||||
|
||||
maskedLookup : Value value -> value
|
||||
maskedLookup (Value lookupSecrets) =
|
||||
case lookupSecrets SecretsDict.masked of
|
||||
Ok value ->
|
||||
value
|
||||
|
||||
Err _ ->
|
||||
-- crash
|
||||
maskedLookup (Value lookupSecrets)
|
||||
|
||||
|
||||
succeed : value -> Value value
|
||||
succeed value =
|
||||
Value (\_ -> Ok value)
|
||||
|
||||
|
||||
buildError : String -> SecretsDict -> BuildError
|
||||
buildError secretName secretsDict =
|
||||
let
|
||||
availableEnvironmentVariables : List String
|
||||
availableEnvironmentVariables =
|
||||
SecretsDict.available secretsDict
|
||||
in
|
||||
{ title = "Missing Secret"
|
||||
, message =
|
||||
[ Terminal.text "I expected to find this Secret in your environment variables but didn't find a match:\n\nSecrets.get \""
|
||||
, Terminal.text secretName
|
||||
, Terminal.text "\"\n "
|
||||
, Terminal.red <| underlineText (secretName |> String.length)
|
||||
, Terminal.text "\n\nSo maybe "
|
||||
, Terminal.yellow <| secretName
|
||||
, Terminal.text " should be "
|
||||
, Terminal.green <| (sortMatches secretName availableEnvironmentVariables |> List.head |> Maybe.withDefault "")
|
||||
]
|
||||
, path = "" -- TODO wire in path here?
|
||||
, fatal = True
|
||||
}
|
||||
|
||||
|
||||
underlineText : Int -> String
|
||||
underlineText length =
|
||||
String.repeat length "^"
|
||||
|
||||
|
||||
sortMatches : String -> List String -> List String
|
||||
sortMatches missingSecret availableSecrets =
|
||||
let
|
||||
simpleMatch : List Fuzzy.Config -> List String -> String -> String -> Int
|
||||
simpleMatch config separators needle hay =
|
||||
Fuzzy.match config separators needle hay |> .score
|
||||
in
|
||||
List.sortBy (simpleMatch [] [] missingSecret) availableSecrets
|
||||
|
||||
|
||||
map : (valueA -> valueB) -> Value valueA -> Value valueB
|
||||
map mapFunction (Value lookupSecrets) =
|
||||
Value
|
||||
(\secrets ->
|
||||
lookupSecrets secrets
|
||||
|> Result.map mapFunction
|
||||
)
|
||||
|
||||
|
||||
with : String -> Value (String -> value) -> Value value
|
||||
with newSecret (Value lookupSecrets) =
|
||||
Value <|
|
||||
\secrets ->
|
||||
case lookupSecrets secrets of
|
||||
Ok value ->
|
||||
case SecretsDict.get newSecret secrets of
|
||||
Just newValue ->
|
||||
value newValue |> Ok
|
||||
|
||||
Nothing ->
|
||||
Err [ buildError newSecret secrets ]
|
||||
|
||||
Err error ->
|
||||
case SecretsDict.get newSecret secrets of
|
||||
Just _ ->
|
||||
Err error
|
||||
|
||||
Nothing ->
|
||||
-- TODO add more errors
|
||||
Err
|
||||
(buildError newSecret secrets
|
||||
:: error
|
||||
)
|
@ -1,45 +0,0 @@
|
||||
module SecretsDict exposing (SecretsDict, available, decoder, get, masked, unmasked)
|
||||
|
||||
import Dict exposing (Dict)
|
||||
import Json.Decode as Decode exposing (Decoder)
|
||||
|
||||
|
||||
available : SecretsDict -> List String
|
||||
available secretsDict =
|
||||
case secretsDict of
|
||||
Masked ->
|
||||
[]
|
||||
|
||||
Unmasked dict ->
|
||||
Dict.keys dict
|
||||
|
||||
|
||||
decoder : Decoder SecretsDict
|
||||
decoder =
|
||||
Decode.dict Decode.string
|
||||
|> Decode.map Unmasked
|
||||
|
||||
|
||||
unmasked : Dict String String -> SecretsDict
|
||||
unmasked dict =
|
||||
Unmasked dict
|
||||
|
||||
|
||||
masked : SecretsDict
|
||||
masked =
|
||||
Masked
|
||||
|
||||
|
||||
get : String -> SecretsDict -> Maybe String
|
||||
get secretName secretsDict =
|
||||
case secretsDict of
|
||||
Masked ->
|
||||
Just <| "<" ++ secretName ++ ">"
|
||||
|
||||
Unmasked dict ->
|
||||
dict |> Dict.get secretName
|
||||
|
||||
|
||||
type SecretsDict
|
||||
= Masked
|
||||
| Unmasked (Dict String String)
|
Loading…
Reference in New Issue
Block a user