Skip to content

Commit

Permalink
feat: add social auth
Browse files Browse the repository at this point in the history
  • Loading branch information
pedronauck committed Mar 5, 2024
1 parent 02aeb26 commit 38ecaa3
Show file tree
Hide file tree
Showing 8 changed files with 501 additions and 310 deletions.
28 changes: 15 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
Faucet App
===
# Faucet App

[![build](https://github.com/FuelLabs/faucet/actions/workflows/ci.yml/badge.svg)](https://github.com/FuelLabs/faucet/actions/workflows/ci.yml)
[![discord](https://img.shields.io/badge/chat%20on-discord-orange?&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2)](https://discord.gg/xfpK4Pe)

A simple faucet app for dispensing tokens on a fuel network. It uses Google captcha for spam resistance
without requiring any social media based identification.

## Configuration

The faucet makes use of environment variables for configuration.

| Environment Variable | Description |
|----------------------|-------------------------------------------------------------------------|
| RUST_LOG | EnvFilter configuration for adjusting logging granularity. |
| HUMAN_LOGGING | If false, logs will be output as machine readable JSON. |
| CAPTCHA_SECRET | The secret key used for enabling Google captcha authentication. |
| CAPTCHA_KEY | The website key used for enabling Google captcha authentication. |
| WALLET_SECRET_KEY | A hex formatted string of the wallet private key that owns some tokens. |
| FUEL_NODE_URL | The GraphQL endpoint for connecting to fuel-core. |
| Environment Variable | Description |
| -------------------- | ----------------------------------------------------------------------------------------------- |
| RUST_LOG | EnvFilter configuration for adjusting logging granularity. |
| HUMAN_LOGGING | If false, logs will be output as machine readable JSON. |
| CAPTCHA_SECRET | The secret key used for enabling Google captcha authentication. |
| CAPTCHA_KEY | The website key used for enabling Google captcha authentication. |
| CLERK_KEY | The key used for enabling clerk authentication. |
| WALLET_SECRET_KEY | A hex formatted string of the wallet private key that owns some tokens. |
| FUEL_NODE_URL | The GraphQL endpoint for connecting to fuel-core. |
| PUBLIC_FUEL_NODE_URL | The public GraphQL endpoint for connecting to fuel-core. Ex.: https://node.fuel.network/graphql |
| SERVICE_PORT | The port the service will listen for http connections on. |
| DISPENSE_AMOUNT | Dispense amount on each faucet |
| MIN_GAS_PRICE | The minimum gas price to use in each transfer |
| SERVICE_PORT | The port the service will listen for http connections on. |
| DISPENSE_AMOUNT | Dispense amount on each faucet |
| MIN_GAS_PRICE | The minimum gas price to use in each transfer |

## Build and Run

Expand Down
13 changes: 8 additions & 5 deletions build.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use minify_html::Cfg;
use std::{env, fs, path::Path};

fn main() {
fn build(page: &str, raw: &[u8]) {
let out_dir = env::var("OUT_DIR").unwrap();
let dest_path = Path::new(&out_dir).join("index.html");
let page = include_bytes!("./static/index.html");
let minified = minify_html::minify(page, &Cfg::spec_compliant());

let dest_path = Path::new(&out_dir).join(page);
let minified = minify_html::minify(raw, &Cfg::spec_compliant());
fs::write(dest_path, minified).expect("failed to save minified index page");
println!("cargo:rerun-if-changed=static");
}

fn main() {
build("index.html", include_bytes!("./static/index.html"));
build("sign_in.html", include_bytes!("./static/sign_in.html"));
}
10 changes: 6 additions & 4 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::constants::{
CAPTCHA_KEY, CAPTCHA_SECRET, DEFAULT_DISPENSE_INTERVAL, DEFAULT_FAUCET_DISPENSE_AMOUNT,
DEFAULT_NODE_URL, DEFAULT_PORT, DISPENSE_AMOUNT, DISPENSE_INTERVAL, FAUCET_ASSET_ID,
FUEL_NODE_URL, HUMAN_LOGGING, LOG_FILTER, MIN_GAS_PRICE, PUBLIC_FUEL_NODE_URL, SERVICE_PORT,
TIMEOUT_SECONDS, WALLET_SECRET_KEY,
CAPTCHA_KEY, CAPTCHA_SECRET, CLERK_KEY, DEFAULT_DISPENSE_INTERVAL,
DEFAULT_FAUCET_DISPENSE_AMOUNT, DEFAULT_NODE_URL, DEFAULT_PORT, DISPENSE_AMOUNT,
DISPENSE_INTERVAL, FAUCET_ASSET_ID, FUEL_NODE_URL, HUMAN_LOGGING, LOG_FILTER, MIN_GAS_PRICE,
PUBLIC_FUEL_NODE_URL, SERVICE_PORT, TIMEOUT_SECONDS, WALLET_SECRET_KEY,
};
use fuels_core::types::AssetId;
use secrecy::Secret;
Expand All @@ -15,6 +15,7 @@ pub struct Config {
pub service_port: u16,
pub captcha_key: Option<String>,
pub captcha_secret: Option<Secret<String>>,
pub clerk_key: Option<String>,
pub node_url: String,
pub public_node_url: String,
pub wallet_secret_key: Option<Secret<String>>,
Expand All @@ -36,6 +37,7 @@ impl Default for Config {
captcha_secret: env::var_os(CAPTCHA_SECRET)
.map(|s| Secret::new(s.into_string().unwrap())),
captcha_key: env::var_os(CAPTCHA_KEY).map(|s| s.into_string().unwrap()),
clerk_key: env::var_os(CLERK_KEY).map(|s| s.into_string().unwrap()),
node_url: env::var(FUEL_NODE_URL).unwrap_or_else(|_| DEFAULT_NODE_URL.to_string()),
public_node_url: env::var(PUBLIC_FUEL_NODE_URL)
.unwrap_or_else(|_| DEFAULT_NODE_URL.to_string()),
Expand Down
1 change: 1 addition & 0 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pub const HUMAN_LOGGING: &str = "HUMAN_LOGGING";
pub const CAPTCHA_KEY: &str = "CAPTCHA_KEY";
pub const CAPTCHA_SECRET: &str = "CAPTCHA_SECRET";
pub const WALLET_SECRET_KEY: &str = "WALLET_SECRET_KEY";
pub const CLERK_KEY: &str = "CLERK_KEY";
pub const PUBLIC_FUEL_NODE_URL: &str = "PUBLIC_FUEL_NODE_URL";
pub const WALLET_SECRET_DEV_KEY: &str =
"99ad179d4f892ff3124ccd817408ff8a4452d9c16bb1b4968b8a59797e13cd7a";
Expand Down
7 changes: 7 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,13 @@ pub async fn start_server(
HeaderValue::from_static("public, max-age=3600, immutable"),
)),
)
.route(
"/sign-in",
get(routes::sign_in).layer(SetResponseHeaderLayer::<_>::overriding(
CACHE_CONTROL,
HeaderValue::from_static("public, max-age=3600, immutable"),
)),
)
.route("/health", get(health))
.route("/dispense", get(routes::dispense_info))
.route(
Expand Down
29 changes: 27 additions & 2 deletions src/routes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ lazy_static::lazy_static! {
}

#[memoize::memoize]
pub fn render_page(public_node_url: String, captcha_key: Option<String>) -> String {
pub fn render_main(
public_node_url: String,
captcha_key: Option<String>,
clerk_key: String,
) -> String {
let template = include_str!(concat!(env!("OUT_DIR"), "/index.html"));
// sub in values
let mut handlebars = Handlebars::new();
Expand All @@ -50,6 +54,7 @@ pub fn render_page(public_node_url: String, captcha_key: Option<String>) -> Stri
let mut data = BTreeMap::new();
data.insert("page_title", "Fuel Faucet");
data.insert("public_node_url", public_node_url.as_str());
data.insert("clerk_public_key", clerk_key.as_str());
// if captcha is enabled, add captcha key
if let Some(captcha_key) = &captcha_key {
data.insert("captcha_key", captcha_key.as_str());
Expand All @@ -58,10 +63,30 @@ pub fn render_page(public_node_url: String, captcha_key: Option<String>) -> Stri
handlebars.render("index", &data).unwrap()
}

#[memoize::memoize]
pub fn render_sign_in(clerk_key: String) -> String {
let template = include_str!(concat!(env!("OUT_DIR"), "/sign_in.html"));
// sub in values
let mut handlebars = Handlebars::new();
handlebars
.register_template_string("index", template)
.unwrap();
let mut data = BTreeMap::new();
data.insert("clerk_public_key", clerk_key.as_str());
// render page
handlebars.render("index", &data).unwrap()
}

pub async fn main(Extension(config): Extension<SharedConfig>) -> Html<String> {
let public_node_url = config.public_node_url.clone();
let captcha_key = config.captcha_key.clone();
Html(render_page(public_node_url, captcha_key))
let clerk_key = config.clerk_key.clone().unwrap();
Html(render_main(public_node_url, captcha_key, clerk_key))
}

pub async fn sign_in(Extension(config): Extension<SharedConfig>) -> Html<String> {
let clerk_key = config.clerk_key.clone().unwrap();
Html(render_sign_in(clerk_key))
}

#[tracing::instrument(skip(wallet))]
Expand Down
Loading

0 comments on commit 38ecaa3

Please sign in to comment.