Skip to content

Instantly share code, notes, and snippets.

@randohinn
Created March 12, 2025 13:05
Show Gist options
  • Save randohinn/58534c774282bdff14904b3c21aa9926 to your computer and use it in GitHub Desktop.
Save randohinn/58534c774282bdff14904b3c21aa9926 to your computer and use it in GitHub Desktop.
kratos self service register flow
<form class="w-full" method="POST" action="{{basePath}}/self-service/registration?flow={{flow.id}}">
{{#each nodes}}
{{#if (eq this.group "default") }}
{{#if (eq this.type "input")}}
{{#if (isnt attributes.type "submit")}}
{{#if (isnt attributes.type "checkbox")}}
<label class="block" for="{{attributes.name}}">
{{#if (lookup ../translation meta.label.text)}}
{{lookup ../translation meta.label.text}}
{{else}}
{{meta.label.text}}
{{/if}}
</label>
<input id="{{attributes.name}}" type="{{attributes.type}}" value="{{attributes.value}}" name="{{attributes.name}}" {{#if attributes.required}} required {{/if}} {{#if (eq attributes.type "checkbox" )}} {{#if (eq attributes.value true)}}checked {{/if}} {{/if}} />
{{else}}
<input id="{{attributes.name}}" type="{{attributes.type}}" name="{{attributes.name}}" {{#if attributes.required}} required {{/if}} {{#if (eq attributes.type "checkbox" )}} {{#if (eq attributes.value true)}}checked {{/if}} {{/if}} />
<label for="{{attributes.name}}">
{{#if (lookup ../translation meta.label.text)}}
{{lookup ../translation meta.label.text}}
{{else}}
{{meta.label.text}}
{{/if}}
</label><br>
{{/if}}
{{/if}}
{{#if (eq attributes.type "submit")}}
<div class="flex items-center justify-end">
<button class="bg-ahhaa text-white block rounded-md mt-2 px-4 py-1.5 font-medium" name="{{attributes.name}}" value="{{attributes.value}}">
{{#if (lookup ../translation meta.label.text)}}
{{lookup ../translation meta.label.text}}
{{else}}
{{meta.label.text}}
{{/if}}
</button>
</div>
{{/if}}
{{/if}}
{{#if (gt messages.length 0 )}}
{{#each messages}}
{{#if (eq this.type "error")}}
<div class="my-2 text-sm text-red-500">
{{#if (lookup ../translation this.id)}}
{{lookup ../translation this.id}}
{{else}}
{{this.id}}
{{/if}}
</div>
{{/if}}
{{/each}}
{{/if}}
{{/if}}
{{#if (eq this.group "password") }}
{{#if (eq this.type "input")}}
{{#if (isnt attributes.type "submit")}}
{{#if (isnt attributes.type "checkbox")}}
<label class="block" for="{{attributes.name}}">
{{#if (lookup ../translation meta.label.text)}}
{{lookup ../translation meta.label.text}}
{{else}}
{{meta.label.text}}
{{/if}}
</label>
<input id="{{attributes.name}}" type="{{attributes.type}}" value="{{attributes.value}}" name="{{attributes.name}}" {{#if attributes.required}} required {{/if}} {{#if (eq attributes.type "checkbox" )}} {{#if (eq attributes.value true)}}checked {{/if}} {{/if}} />
{{else}}
<input id="{{attributes.name}}" type="{{attributes.type}}" value="{{attributes.value}}" name="{{attributes.name}}" {{#if attributes.required}} required {{/if}} {{#if (eq attributes.type "checkbox" )}} {{#if (eq attributes.value true)}}checked {{/if}} {{/if}} />
<label for="{{attributes.name}}">
{{#if (lookup ../translation meta.label.text)}}
{{lookup ../translation meta.label.text}}
{{else}}
{{meta.label.text}}
{{/if}}
</label><br>
{{/if}}
{{/if}}
{{/if}}
{{#if (gt messages.length 0 )}}
{{#each messages}}
{{#if (eq this.type "error")}}
<div class="my-2 text-sm text-red-500">
{{#if (lookup ../translation this.id)}}
{{lookup ../translation this.id}}
{{else}}
{{this.id}}
{{/if}}
</div>
{{/if}}
{{/each}}
{{/if}}
{{/if}}
{{#if (eq attributes.type "submit")}}
<div class="flex items-center justify-end">
<button class="bg-ahhaa text-white block rounded-md mt-2 px-4 py-1.5 font-medium w-auto" name="{{attributes.name}}" value="{{attributes.value}}">
{{#if (lookup ../translation meta.label.text)}}
{{lookup ../translation meta.label.text}}
{{else}}
{{meta.label.text}}
{{/if}}
</button>
</div>
{{/if}}
{{/each}}
</form>
const globals = require('../globals');
const frontend = globals.frontend;
function customSort(a, b) {
const nameA = a.attributes.name;
const nameB = b.attributes.name;
const aContainsEmail = nameA.includes("email");
const bContainsEmail = nameB.includes("email");
const aContainsPassword = nameA.includes("password");
const bContainsPassword = nameB.includes("password");
const aIsAgreement = nameA.startsWith("traits.agreements");
const bIsAgreement = nameB.startsWith("traits.agreements");
const aContainsFirstName = nameA.includes("traits.name.first");
const bContainsFirstName = nameB.includes("traits.name.first");
const aContainsLastName = nameA.includes("traits.name.last");
const bContainsLastName = nameB.includes("traits.name.last");
if (aContainsFirstName && bContainsLastName) {
return -1; // a comes before b
} else if (aContainsLastName && bContainsFirstName) {
return 1; // a comes after b
} else if ((aContainsFirstName || aContainsLastName) && !(bContainsFirstName || bContainsLastName)) {
return -1; // a comes before b
} else if (!(aContainsFirstName || aContainsLastName) && (bContainsFirstName || bContainsLastName)) {
return 1; // a comes after b
} else if (aContainsEmail && !bContainsEmail) {
return -1; // a comes before b
} else if (!aContainsEmail && bContainsEmail) {
return 1; // a comes after b
} else if (aContainsPassword && !bContainsPassword) {
return -1; // a comes before b
} else if (!aContainsPassword && bContainsPassword) {
return 1; // a comes after b
} else if (aIsAgreement && !bIsAgreement) {
return -1; // a comes before b
} else if (!aIsAgreement && bIsAgreement) {
return 1; // a comes after b
} else {
return 0; // no specific order
}
}
module.exports = function(app) {
app.get('/registration',function(req, res) {
const {
flow,
return_to,
after_verification_return_to,
login_challenge,
organization,
} = req.query
const initFlowQuery = new URLSearchParams({
...(return_to && { return_to: return_to.toString() }),
...(organization && { organization: organization.toString() }),
...(after_verification_return_to && {
after_verification_return_to: after_verification_return_to.toString(),
}),
})
if (globals.isQuerySet(login_challenge)) {
initFlowQuery.append("login_challenge", login_challenge)
}
if (!globals.isQuerySet(flow)) {
res.redirect(303, globals.getUrlForFlow(process.env.KRATOS_BROWSER_URL || "localhost:4433",'registration',initFlowQuery));
return
}
frontend.getRegistrationFlow({id: flow, cookie: req.header("cookie")}).then(async ({ data: flow }) => {
res.render('registration', {
flow: flow,
nodes: flow.ui.nodes.slice().sort(customSort),
title: `Registreeru - AHHAA Konto`,
session: req.session,
});
});
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment