diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d59f95f --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +Makefile.inc diff --git a/Makefile b/Makefile index 33a6ff9..8946a7f 100644 --- a/Makefile +++ b/Makefile @@ -10,9 +10,10 @@ CLIENT_ID = PUT_YOUR_CLIENT_ID_HERE CLIENT_SECRET = PUT_YOUR_CLIENT_SECRET_HERE TENANT_ID = your-tenant -SERVER_ID = your-workspace-id ISSUER_URL = https://your-tenant.your-region.authz.cloudentity.io/your-tenant/admin +SERVER_ID = your-workspace-id THEME_ID = demo +THEME_DIR = theme # # Set TENANT_ID and ISSUER_URL appropriately for your client. # Your client should be in the 'admin' workspace, but SERVER_ID can be any workspace @@ -66,7 +67,7 @@ delete-theme: ## Delete a theme --header 'Authorization: Bearer ${TOKEN}' upsert-templates: ## Insert or Update all templates - for f in $$(cd theme; find * -name '*.tmpl'); \ + for f in $$(cd ${THEME_DIR}; find * -name '*.tmpl'); \ do make upsert-template THEME_ID=${THEME_ID} TEMPLATE_PATH="$$f" TOKEN=${TOKEN} ; \ done @@ -74,7 +75,7 @@ upsert-template: ## Insert or Update one template (make upsert-template TEMPLATE ${CURL} -D - -X PUT '${BASEURL}/api/admin/${TENANT_ID}/theme/${THEME_ID}/template/${TEMPLATE_PATH}' \ --header 'Authorization: Bearer ${TOKEN}' \ --header 'Content-Type: application/json' \ - --data-binary @<(jq -M --raw-input --slurp < 'theme/${TEMPLATE_PATH}' '{"content":.}') + --data-binary @<(jq -M --raw-input --slurp < '${THEME_DIR}/${TEMPLATE_PATH}' '{"content":.}') delete-template: ## Delete a template (make delete-template TEMPLATE_PATH=pages/authorization/login/scripts.tmpl) ${CURL} -D - -X DELETE '${BASEURL}/api/admin/${TENANT_ID}/theme/${THEME_ID}/template/${TEMPLATE_PATH}' \ diff --git a/README.md b/README.md index c0ea443..9fb2a49 100644 --- a/README.md +++ b/README.md @@ -25,9 +25,12 @@ If a situation comes up in which it's absolutely necessary for someone to make a ## How to use the Makefile/CLI +Prerequisites: +- `jq` - A command line [JSON processor](https://github.com/stedolan/jq). + You will need to create an ACP Client named 'manage-themes' in the Admin workspace with the application type `Service`. -> Note: If the `Service` application type is not available, in the Admin workspace, navigate to "Auth Setttings > OAuth," and under "Allowed Grant types," make sure "Client credentials" is selected. +> **Note:** If the `Service` application type is not available, in the Admin workspace, navigate to "Auth Settings > OAuth," and under "Allowed Grant types," make sure "Client credentials" is selected. Confirm these OAuth settings after you have created the client: @@ -40,11 +43,14 @@ Now create a file named `Makefile.inc` that overrides the following default valu CLIENT_ID = PUT_YOUR_CLIENT_ID_HERE CLIENT_SECRET = PUT_YOUR_CLIENT_SECRET_HERE TENANT_ID = your-tenant -SERVER_ID = your-workspace-id ISSUER_URL = https://your-tenant.your-region.authz.cloudentity.io/your-tenant/admin +SERVER_ID = your-workspace-id THEME_ID = demo +THEME_DIR = theme ``` +> **Note:** The `ISSUER_URL` is related to the OAuth client in the Admin workspace, thus the path pattern is `your-tenant/admin`. The `SERVER_ID` refers to the ID of the **workspace** to which the theme is to be bound. **NEVER** put `admin` as the value for `SERVER_ID`, as using a custom theme that is bound to the admin workspace has the potential to lock you out of your tenant if you make an edit in the custom theme templates that results in certain types of errors. Always use a dedicated test workspace for actively developing the theme. + **IMPORTANT:** When working with a "vanity domain" that does not have a tenant ID in the URL params for API requests, leave the value of the `TENANT_ID` variable blank in the `Makefile.inc`, and set the value of `ISSUER_URL` without the `TENANT_ID` param, as shown below: ``` @@ -54,6 +60,8 @@ ISSUER_URL = https://vanity-domain.your-organization.com/admin > **Note:** `SERVER_ID` refers to the ID of the workspace to which you intend to bind your theme. +The `THEME_DIR` value indicates which directory should be used as the local source of the templates when 'upsert' commands are used. When creating a custom theme, it is possible to leave the default theme unedited as a reference, and set up a custom theme directory with a copy of the whole theme (or containing only a subset of templates to be altered, as long as the directory structure matches that of the default theme). In this case, change the value of `THEME_DIR` to the path of your custom directory. For example, this could be something like `my-custom-themes/demo-theme-1`, where `my-custom-themes` is located in the project root, and with `demo-theme-1` containing the `pages` and `shared` directories, etc. + To test that the makefile is working, you can do `make list-base-templates` to query ACP: ``` $ make list-base-templates diff --git a/custom-theme-examples/financroo-demo/pages/authorization/demo/index.tmpl b/custom-theme-examples/financroo-demo/pages/authorization/demo/index.tmpl new file mode 100644 index 0000000..7e1a546 --- /dev/null +++ b/custom-theme-examples/financroo-demo/pages/authorization/demo/index.tmpl @@ -0,0 +1,81 @@ +{{ template "base" . }} + +{{ define "title" }}Demo{{ end }} + +{{ define "content" }} + {{ template "demo_scripts" . }} + + {{ if .Data.FlowCompleted }} +
+ {{ template "header" .Styling }} + + + + +
+ +
+
+

Demo Application

+ +
+
+ error_outline +
+

You have logged in to the Demo app

+

+ The information below is used for demo and testing purposes. + You can view aggregated claims or the tokens issued by ACP below. +

+
+
+
+ +
+ + + + + {{ if .Data.IDTokenRaw }} + + {{ end }} + + {{ if .Data.RefreshTokenRaw }} + + {{ end }} +
+
+
+ +
+ {{ template "demo-claims-tab" . }} + {{ template "demo-access-token-tab" . }} + {{ template "demo-id-token-tab" . }} + {{ template "demo-refresh-token-tab" . }} +
+ + {{ else }} +
+ {{ template "header" .Config }} +
+ +
+ +

Demo {{ .flow }} application

+ + {{ if eq .Data.Flow "device" }} + {{ template "demo-unauthorized" . }} + {{ else }} + {{ template "demo-login" . }} + {{ end }} +
+ {{ end }} +{{ end }} diff --git a/custom-theme-examples/financroo-demo/pages/authorization/login/index.tmpl b/custom-theme-examples/financroo-demo/pages/authorization/login/index.tmpl new file mode 100644 index 0000000..017a395 --- /dev/null +++ b/custom-theme-examples/financroo-demo/pages/authorization/login/index.tmpl @@ -0,0 +1,53 @@ +{{ template "base" . }} + +{{ define "title" }} Login {{ end }} + +{{ define "content" }} + {{ template "login_scripts" . }} + {{ template "password_visibility_script" . }} + +
+
+
+
+
+ +
+
+
+ {{ template "header" .Config }} +
+ +
+ {{ if not .Data.HasIDPs }} + {{ template "login_no_idp" . }} + {{ else }} +
+
+ {{ if .Data.HasAdminTabs }} + {{ template "login_admin_tabs" }} + {{ end }} + +
+
+ {{ template "login_content" . }} +
+
+ + {{ template "login_admin_quick_access" . }} +
+ +
+ Cancel +
+
+ {{ end }} +
+ + {{ template "footer" }} + +
+
+
+
+{{ end }} diff --git a/custom-theme-examples/financroo-demo/pages/authorization/login/login_content_mode_idps_list.tmpl b/custom-theme-examples/financroo-demo/pages/authorization/login/login_content_mode_idps_list.tmpl new file mode 100644 index 0000000..1da9afe --- /dev/null +++ b/custom-theme-examples/financroo-demo/pages/authorization/login/login_content_mode_idps_list.tmpl @@ -0,0 +1,151 @@ +{{ define "login_content_mode_idps_list" }} + +
+ + +
+ error_outline + Failed to fetch IDPs +
+ +
+ error_outline + Authentication is not supported for this user/domain +
+ + {{ if .Data.RememberedSignInMethod }} + {{ template "login_content_remembered_idp" . }} + {{ else }} + {{ if .Data.IDPDiscoveryEnabled }} +

Sign into your account

+
+ {{ .Data.CsrfField }} + +
+ + +
+ + +
+ + {{ else }} +

Select how you want to sign in

+ + + {{ end }} + {{ end }} + +
+ {{ if or .Data.RememberedSignInMethod .Data.IDPDiscoveryEnabled }} +
Sign in with
+ {{ end }} +
+ +
+ {{ range $method := .Data.Methods }} + + {{ end }} +
+ +
+ +
+ + {{ if .Data.IDPDiscoveryEnabled }} + + {{ end }} + +
+ +{{ end }} diff --git a/custom-theme-examples/financroo-demo/pages/authorization/login/login_content_mode_static_idp.tmpl b/custom-theme-examples/financroo-demo/pages/authorization/login/login_content_mode_static_idp.tmpl new file mode 100644 index 0000000..9346376 --- /dev/null +++ b/custom-theme-examples/financroo-demo/pages/authorization/login/login_content_mode_static_idp.tmpl @@ -0,0 +1,65 @@ +{{ define "login_content_mode_static_idp" }} + +
+ + + + + {{ range .Data.FormError.Errors }} +
+
+ error_outline + {{ .Message }} +
+
+ {{ end }} + + {{ if gt (len .Data.Methods) 1 }} + + {{ end }} + +

Sign into your account

+ +
+ {{ .Data.CsrfField }} + + {{ if and .Data.IDP.SettingsHint (gt (len .Data.IDP.Credentials.Users) 0) }} +
+

This is a mock IDP login page.

+
+
Username: {{ (index .Data.IDP.Credentials.Users 0).Username }}
+
Password: {{ (index .Data.IDP.Credentials.Users 0).Password }}
+
+
+ {{ end }} + +
+ + +
+ +
+ +
+ + +
+
+ + + + +
+ +
+ +{{ end }} diff --git a/custom-theme-examples/financroo-demo/pages/error/index.tmpl b/custom-theme-examples/financroo-demo/pages/error/index.tmpl new file mode 100644 index 0000000..828fd5b --- /dev/null +++ b/custom-theme-examples/financroo-demo/pages/error/index.tmpl @@ -0,0 +1,42 @@ +{{ template "base" . }} + +{{ define "title" }}Error{{ end }} + +{{ define "content" }} + +
+ {{ template "header" .Config }} +
+ +
+ + + +
{{ .Data.Name }}
+ +
+ error_outline + {{ .Data.Description }}. +
+ + {{ if .Data.Hint }} +
{{ .Data.Hint }}
+ {{ end }} + + {{ if .Data.RetryURL }} +
+ Retry + {{ end }} + + {{ if .Data.Version }} +
Version: {{ .Data.Version }}
+ {{ end }} + + {{ if .Data.TraceID }} +
ID: {{ .Data.TraceID }}
+ {{ end }} +
+ +{{ template "footer" }} + +{{ end }} diff --git a/custom-theme-examples/financroo-demo/pages/identity/login/authn_mode_password.tmpl b/custom-theme-examples/financroo-demo/pages/identity/login/authn_mode_password.tmpl new file mode 100644 index 0000000..b7b5fc2 --- /dev/null +++ b/custom-theme-examples/financroo-demo/pages/identity/login/authn_mode_password.tmpl @@ -0,0 +1,73 @@ +{{ define "authn_password" }} + +

Sign into your account

+ +
+ + +
+ +
+ + +
+ + +
+
+ + + + {{ if .Data.AuthnModeSwitch }} + +
+ + +
+
or sign in with
+
+ +
+ + {{ if .Data.AuthenticationMechanismsAvailability.otp }} + + {{ end }} + + {{ if .Data.AuthenticationMechanismsAvailability.webauthn }} + + {{ end }} + +
+
+ {{ end }} + + + + +{{ end }} diff --git a/custom-theme-examples/financroo-demo/pages/identity/login/index.tmpl b/custom-theme-examples/financroo-demo/pages/identity/login/index.tmpl new file mode 100644 index 0000000..6687b22 --- /dev/null +++ b/custom-theme-examples/financroo-demo/pages/identity/login/index.tmpl @@ -0,0 +1,40 @@ +{{ template "base" . }} + +{{ define "title" }}Login{{ end }} + +{{ define "content" }} + {{ template "identity_login_scripts" . }} + {{ template "password_visibility_script" . }} + +
+
+
+
+
+ +
+
+
+ {{ template "header" .Config }} +
+ +
+
+ + {{ if .Data.AuthnView }} + {{ template "authn" . }} + {{ else }} +
No Authentication Mechanisms Enabled
+ {{ end }} + +
+
+ + {{ template "footer" }} + +
+
+
+
+ +{{ end }} diff --git a/custom-theme-examples/financroo-demo/pages/identity/register/index.tmpl b/custom-theme-examples/financroo-demo/pages/identity/register/index.tmpl new file mode 100644 index 0000000..dcd08bd --- /dev/null +++ b/custom-theme-examples/financroo-demo/pages/identity/register/index.tmpl @@ -0,0 +1,47 @@ +{{ template "base" . }} + +{{ define "title" }}Register{{ end }} + +{{ define "content" }} + +
+
+
+
+
+ +
+
+ +
+ {{ template "header" .Config }} +
+ + {{ template "identity_register_scripts" . }} + {{ template "password_visibility_script" . }} + {{ template "submit_button_disabling_script" . }} + +
+
+

Sign up for a new account

+ + {{ template "form" . }} + + {{ range .Data.FormError.Errors }} + {{ template "error_message" . }} + {{ end }} + + +
+
+ + {{ template "footer" }} + +
+
+
+
+ +{{ end }} diff --git a/custom-theme-examples/financroo-demo/shared/base.tmpl b/custom-theme-examples/financroo-demo/shared/base.tmpl new file mode 100644 index 0000000..d21cddc --- /dev/null +++ b/custom-theme-examples/financroo-demo/shared/base.tmpl @@ -0,0 +1,28 @@ +{{ define "base" }} + + + + + + + + {{ template "title" . }} + + + + + + + + + + {{ template "styles_financroo" . }} + + + + {{ template "content" . }} + + + +{{ end }} diff --git a/custom-theme-examples/financroo-demo/shared/footer.tmpl b/custom-theme-examples/financroo-demo/shared/footer.tmpl new file mode 100644 index 0000000..c2b89d9 --- /dev/null +++ b/custom-theme-examples/financroo-demo/shared/footer.tmpl @@ -0,0 +1,7 @@ +{{ define "footer" }} + + + +{{ end }} diff --git a/custom-theme-examples/financroo-demo/shared/header.tmpl b/custom-theme-examples/financroo-demo/shared/header.tmpl new file mode 100644 index 0000000..c729f7a --- /dev/null +++ b/custom-theme-examples/financroo-demo/shared/header.tmpl @@ -0,0 +1,7 @@ +{{ define "header" }} + + + +{{ end }} diff --git a/custom-theme-examples/financroo-demo/shared/styles_financroo.tmpl b/custom-theme-examples/financroo-demo/shared/styles_financroo.tmpl new file mode 100644 index 0000000..9a871f7 --- /dev/null +++ b/custom-theme-examples/financroo-demo/shared/styles_financroo.tmpl @@ -0,0 +1,1628 @@ +{{ define "styles_financroo" }} + + + +{{ end }}