diff --git a/docker-compose.yml b/docker-compose.yml index ee997ec..3395fe9 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -45,6 +45,18 @@ services: networks: - search_net + mailcatcher: + image: sj26/mailcatcher + ports: + - "1025:1025" + - "1080:1080" + healthcheck: + interval: 10s + retries: 80 + test: wget -q -O /dev/null http://mailcatcher:1080/ + networks: + - mailcatcher_net + fusionauth: image: fusionauth/fusionauth-app:latest depends_on: @@ -52,6 +64,8 @@ services: condition: service_healthy search: condition: service_healthy + mailcatcher: + condition: service_healthy environment: DATABASE_URL: jdbc:postgresql://db:5432/fusionauth DATABASE_ROOT_USERNAME: ${POSTGRES_USER} @@ -67,6 +81,7 @@ services: networks: - db_net - search_net + - mailcatcher_net restart: unless-stopped ports: - 9011:9011 @@ -79,6 +94,8 @@ networks: driver: bridge search_net: driver: bridge + mailcatcher_net: + driver: bridge volumes: db_data: diff --git a/kickstart/css/styles.css b/kickstart/css/styles.css index 4ba979e..f1f3422 100644 --- a/kickstart/css/styles.css +++ b/kickstart/css/styles.css @@ -80,6 +80,37 @@ .form-row:last-of-type { margin-bottom: 0; } + .magic.login-button > div .icon { + display: none; + } + .magic.login-button > div .text { + font-size: 15px; + overflow: visible; + } + .magic.login-button { + font-size: 1.125rem !important; + border-radius: .5rem; + padding: 1rem !important; + line-height: normal !important; + letter-spacing: normal !important; + } + .login-button.magic { + background: var(--main-accent-color) !important; + width: 100%; + margin-top: 2.5rem; + } + .login-button.magic:hover { + opacity: .8 !important; + background: var(--main-accent-color) !important; + } + .login-button.magic:focus { + background: var(--main-accent-color) !important; + box-shadow: inset 0 1px 2px rgba(0,0,0,0.4),0 0 0 2px rgba(57,152,219,0.4); + outline: 1px solid #ffffff !important; + } + .login-button.magic > .fa { + display: none; + } .button { font-size: 1.125rem !important; border-radius: .5rem; diff --git a/kickstart/email-templates/magic-link.html b/kickstart/email-templates/magic-link.html new file mode 100644 index 0000000..e4120c5 --- /dev/null +++ b/kickstart/email-templates/magic-link.html @@ -0,0 +1,9 @@ +[#setting url_escaping_charset="UTF-8"] +You have requested to log into ChangeBank using this email address. If you do not recognize this request please ignore this email. +

+ [#-- The optional 'state' map provided on the Start Passwordless API call is exposed in the template as 'state' --] + [#assign url = "http://localhost:9011/oauth2/passwordless/${code}?postMethod=true&tenantId=${user.tenantId}" /] + [#list state!{} as key, value][#if key != "tenantId" && value??][#assign url = url + "&" + key?url + "=" + value?url/][/#if][/#list] + ${url} +

+- ChangeBank Admin diff --git a/kickstart/email-templates/magic-link.txt b/kickstart/email-templates/magic-link.txt new file mode 100644 index 0000000..dd9527c --- /dev/null +++ b/kickstart/email-templates/magic-link.txt @@ -0,0 +1,10 @@ +[#setting url_escaping_charset="UTF-8"] +You have requested to log into ChangeBank using this email address. If you do not recognize this request please ignore this email. + +[#-- The optional 'state' map provided on the Start Passwordless API call is exposed in the template as 'state' --] +[#assign url = "http://localhost:9011/oauth2/passwordless/${code}?postMethod=true&tenantId=${user.tenantId}" /] +[#list state!{} as key, value][#if key != "tenantId" && value??][#assign url = url + "&" + key?url + "=" + value?url/][/#if][/#list] + +${url} + +- ChangeBank Admin diff --git a/kickstart/kickstart.json b/kickstart/kickstart.json index 4e4c031..a4905df 100644 --- a/kickstart/kickstart.json +++ b/kickstart/kickstart.json @@ -5,6 +5,7 @@ "applicationId": "e9fdb985-9173-4e01-9d73-ac2d60d1dc8e", "clientSecret": "super-secret-secret-that-should-be-regenerated-for-production", "newThemeId": "#{UUID()}", + "magicLinkTemplateId": "#{UUID()}", "defaultTenantId": "d7d09513-a3f5-401c-9685-34ab6c552453", "adminEmail": "admin@example.com", "adminPassword": "password", @@ -38,7 +39,7 @@ "tenantId": "#{defaultTenantId}", "body": { "application": { - "name": "ExampleNodeApp", + "name": "Start Here App", "oauthConfiguration": { "authorizedRedirectURLs": [ "http://localhost:8080/oauth-redirect" @@ -111,7 +112,7 @@ "body": { "sourceThemeId": "75a068fd-e94b-451a-9aeb-3ddb9a3b5987", "theme": { - "name": "React theme" + "name": "Start here theme" } } }, @@ -132,6 +133,43 @@ "themeId": "#{newThemeId}" } } + }, + { + "method": "PATCH", + "url": "/api/tenant/#{defaultTenantId}", + "body": { + "tenant": { + "emailConfiguration": { + "host": "mailcatcher", + "port": 1025 + } + } + } + }, + { + "method": "POST", + "url": "/api/email/template/#{magicLinkTemplateId}", + "body": { + "emailTemplate": { + "defaultFromName": "No Reply", + "defaultSubject": "Log in", + "defaultHtmlTemplate": "@{email-templates/magic-link.html}", + "defaultTextTemplate": "@{email-templates/magic-link.txt}", + "fromEmail": "no-replay@changebank.com", + "name": "Magic Link Login" + } + } + }, + { + "method": "PATCH", + "url": "/api/tenant/#{defaultTenantId}", + "body": { + "tenant": { + "emailConfiguration": { + "passwordlessEmailTemplateId": "#{magicLinkTemplateId}" + } + } + } } ] }