fix: merge conflicts. remove import in quickstart

This commit is contained in:
Felix Dubrownik
2023-03-03 12:49:56 +01:00
105 changed files with 12072 additions and 28650 deletions

View File

@ -11,7 +11,9 @@ import TabItem from '@theme/TabItem';
# Angular
In this guide you will learn how to add authentication to your Angular application using the Hanko custom element.
In this guide you will learn how to use the
[hanko-elements](https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md) web components to
add authentication and a user profile to your Angular application.
## Install dependencies
@ -21,7 +23,7 @@ Install the `@teamhanko/hanko-elements` package:
npm install @teamhanko/hanko-elements
```
## Register custom element with Angular
## Define custom elements schema
Angular requires you to explicitly declare that you are using custom elements inside your Angular modules, otherwise
it will fail during build complaining about unknown elements. To do so, import the
@ -46,13 +48,12 @@ import { AppComponent } from './app.component';
})
export class AppModule { }
```
## Add `<hanko-auth>` component
## Import & use custom element
Import the `register` function from `@teamhanko/hanko-elements` in the component where you want to use the
Hanko custom element. Call `register` to register the `<hanko-auth>` element with the browser's
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry). Then use the
element in your component template.
To provide a login interface in your app, use the `<hanko-auth>` web component. To do so, first import the `register` function
from `@teamhanko/hanko-elements` in your Angular component. Then call `register` to register the `<hanko-auth>` element with
the browser's [`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry) and use
the element in your component template.
:::info
@ -67,8 +68,8 @@ If you are self-hosting you need to provide the URL of your running Hanko backen
<TabItem value="html" label="login.component.html">
```
```html title="login.component.html" showLineNumbers
<hanko-auth [api]="hankoApi" [lang]="hankoLang"></hanko-auth>
```html showLineNumbers
<hanko-auth [api]="hankoApi" />
```
```mdx-code-block
@ -76,9 +77,8 @@ If you are self-hosting you need to provide the URL of your running Hanko backen
<TabItem value="ts" label="login.component.ts">
```
```js title="login.component.ts" showLineNumbers
```js showLineNumbers
import { Component } from '@angular/core';
import { environment } from '../../../environments/environment';
import { register } from '@teamhanko/hanko-elements';
@Component({
@ -87,8 +87,7 @@ import { register } from '@teamhanko/hanko-elements';
styleUrls: ['./login.component.css']
})
export class LoginComponent {
hankoApi = environment.hankoApi;
hankoLang = environment.hankoLang;
hankoApi = "<YOUR_API_URL>";
constructor() {
// register the component
@ -106,12 +105,12 @@ export class LoginComponent {
</Tabs>
```
## Defining login callbacks
### Define login callbacks
The `<hanko-auth>` element dispatches a custom `hankoAuthSuccess` event on successful login. React to this
event in order to, for example, redirect your users to protected pages in your application.
event to redirect your users to protected pages in your application, e.g. a [user profile page](#hanko-profile).
To do so, you can use Angular's event binding mechanism and supply a callback function that is defined in your component
You can use Angular's event binding mechanism and supply a callback function that is defined in your component
class directly on the `<hanko-auth>` element:
```mdx-code-block
@ -119,12 +118,10 @@ class directly on the `<hanko-auth>` element:
<TabItem value="html" label="login.component.html">
```
```html {2} title="login.component.html" showLineNumbers
```html {2} showLineNumbers
<hanko-auth
(hankoAuthSuccess)="redirectAfterLogin()"
[api]="hankoApi"
[lang]="hankoLang">
</hanko-auth>
[api]="hankoApi" />
```
```mdx-code-block
@ -132,9 +129,8 @@ class directly on the `<hanko-auth>` element:
<TabItem value="ts" label="login.component.ts">
```
```js {3,15,24-27} title="login.component.ts" showLineNumbers
```js {2,13,22-25} showLineNumbers
import { Component } from '@angular/core';
import { environment } from '../../../environments/environment';
import { Router } from '@angular/router';
import { register } from '@teamhanko/hanko-elements';
@ -144,8 +140,7 @@ import { register } from '@teamhanko/hanko-elements';
styleUrls: ['./login.component.css'],
})
export class LoginComponent {
hankoApi = environment.hankoApi;
hankoLang = environment.hankoLang;
hankoApi = "<YOUR_API_URL>";
constructor(private router: Router) {
// register the component
@ -153,7 +148,7 @@ export class LoginComponent {
register({ shadow: true })
.catch((error) => {
// handle error
});
})
}
redirectAfterLogin() {
@ -168,11 +163,70 @@ export class LoginComponent {
</Tabs>
```
## UI customization
## Add `<hanko-profile>` component {#hanko-profile}
The styles of the `hanko-auth` element can be customized using CSS variables and parts. See our guide
on customization [here](https://github.com/teamhanko/hanko/tree/main/frontend/elements#ui-customization).
To provide a page where users can manage their email addresses, password and passkeys, use the `<hanko-profile>` web
component. Just as with the `<hanko-auth>` component, import the `register` function from `@teamhanko/hanko-elements` in
your Angular component. Then call `register` to register the `<hanko-profile>` element with the browser's
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry) and use
the element in your component template.
## Backend request authentication
:::info
When adding the `<hanko-profile>` element to your template you must provide the URL of the Hanko API via the `api`
attribute. If you are using [Hanko Cloud](https://cloud.hanko.io), you can find the API URL on your project dashboard.
If you are self-hosting you need to provide the URL of your running Hanko backend.
:::
```mdx-code-block
<Tabs>
<TabItem value="html" label="profile.component.html">
```
```html showLineNumbers
<hanko-profile [api]="hankoApi" />
```
```mdx-code-block
</TabItem>
<TabItem value="ts" label="profile.component.ts">
```
```js showLineNumbers
import { Component } from '@angular/core';
import { register } from '@teamhanko/hanko-elements';
@Component({
selector: 'app-profile',
templateUrl: './profile.component.html',
styleUrls: ['./profile.component.css']
})
export class ProfileComponent {
hankoApi = "<YOUR_API_URL>";
constructor() {
// register the component
// see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
register({ shadow: true })
.catch((error) => {
// handle error
});
}
}
```
```mdx-code-block
</TabItem>
</Tabs>
```
## Customize component styles
The styles of the `hanko-auth` and `hanko-profile` elements can be customized using CSS variables and parts. See our
guide on customization [here](https://github.com/teamhanko/hanko/tree/main/frontend/elements#ui-customization).
## Authenticate backend requests
If you want to authenticate requests in your own backend, please view our [backend guide](/guides/backend).

View File

@ -8,7 +8,9 @@ sidebar_custom_props:
# Next.js
In this guide you will learn how to add authentication to your Next.js application using the Hanko custom element.
In this guide you will learn how to use the
[hanko-elements](https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md) web components to
add authentication and a user profile to your Next.js application.
## Install dependencies
@ -18,12 +20,12 @@ Install the `@teamhanko/hanko-elements` package:
npm install @teamhanko/hanko-elements
```
## Import & use custom element
## Add `<hanko-auth>` component
Import the `register` function from `@teamhanko/hanko-elements` in the component where you want to use the
Hanko custom element. Call `register` to register the `<hanko-auth>` element with the browser's
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry).
Then use the `<hanko-auth>` element in your JSX.
To provide a login interface in your app, use the `<hanko-auth>` web component. To do so, first import the `register`
function from `@teamhanko/hanko-elements` in your Next.js component. Then call `register` to register the `<hanko-auth>`
element with the browser's [`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry)
and use the `<hanko-auth>` element in your JSX.
:::info
@ -36,11 +38,9 @@ If you are self-hosting you need to provide the URL of your running Hanko backen
```jsx title="HankoAuth.jsx" showLineNumbers
import { register } from "@teamhanko/hanko-elements";
const api = process.env.NEXT_PUBLIC_HANKO_API!;
const lang = process.env.NEXT_PUBLIC_HANKO_LANG;
const hankoApi = "<YOUR_API_URL>";
export default function HankoAuth() {
useEffect(() => {
// register the component
// see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
@ -51,7 +51,7 @@ export default function HankoAuth() {
}, []);
return (
<hanko-auth api={api} lang={lang} />
<hanko-auth api={hankoApi} />
);
}
```
@ -82,20 +82,20 @@ export default function Home() {
}
```
## Defining login callbacks
### Define login callbacks
The `<hanko-auth>` element dispatches a custom `hankoAuthSuccess` event on successful login. React to this
event in order to, for example, redirect your users to protected pages in your application.
event in order to, for example, redirect your users to protected pages in your application,
e.g. a [user profile page](#hanko-profile).
To do so, apply an event listener with an appropriate redirect callback:
```jsx {2,9-20} title="HankoAuth.jsx" showLineNumbers
import React, { useEffect } from "react";
```jsx {2,10-19} title="HankoAuth.jsx" showLineNumbers
import React, { useEffect, useCallback } from "react";
import { useRouter } from "next/router";
import { register } from "@teamhanko/hanko-elements";
const api = process.env.NEXT_PUBLIC_HANKO_API!;
const lang = process.env.NEXT_PUBLIC_HANKO_LANG;
const hankoApi = "<YOUR_API_URL>";
export default function HankoAuth() {
const router = useRouter();
@ -121,17 +121,56 @@ export default function HankoAuth() {
}, []);
return (
<hanko-auth api={api} lang={lang} />
<hanko-auth api={hankoApi} />
);
}
```
## UI customization
## Add `<hanko-profile>` component {#hanko-profile}
The styles of the `hanko-auth` element can be customized using CSS variables and parts. See our guide
on customization [here](https://github.com/teamhanko/hanko/tree/main/frontend/elements#ui-customization).
To provide a page where users can manage their email addresses, password and passkeys, use the `<hanko-profile>` web
component. Just as with the `<hanko-auth>` component, import the `register` function from `@teamhanko/hanko-elements` in
your Next.js component. Then call `register` to register the `<hanko-profile>` element with the browser's
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry) and use
the element in your JSX.
## Backend request authentication
:::info
When adding the `<hanko-profile>` element to your template you must provide the URL of the Hanko API via the `api`
attribute. If you are using [Hanko Cloud](https://cloud.hanko.io), you can find the API URL on your project dashboard.
If you are self-hosting you need to provide the URL of your running Hanko backend.
:::
```jsx title="HankoProfile.jsx" showLineNumbers
import { useEffect } from "react";
import { register } from "@teamhanko/hanko-elements";
const hankoApi = "<YOUR_API_URL>";
export default function HankoProfile() {
useEffect(() => {
// register the component
// see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
register({ shadow: true })
.catch((error) => {
// handle error
});
}, []);
return (
<hanko-profile api={hankoApi} />
);
};
```
## Customize component styles
The styles of the `hanko-auth` and `hanko-profile` elements can be customized using CSS variables and parts. See our
guide on customization [here](https://github.com/teamhanko/hanko/tree/main/frontend/elements#ui-customization).
## Authenticate backend requests
If you want to authenticate requests in your own backend, please view our [backend guide](/guides/backend).

View File

@ -8,7 +8,9 @@ sidebar_custom_props:
# React
In this guide you will learn how to add authentication to your React application using the Hanko custom element.
In this guide you will learn how to use the
[hanko-elements](https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md) web components to
add authentication and a user profile to your React application.
## Install dependencies
Install the `@teamhanko/hanko-elements` package:
@ -17,12 +19,12 @@ Install the `@teamhanko/hanko-elements` package:
npm install @teamhanko/hanko-elements
```
## Import & use custom element
## Add `<hanko-auth>` component
Import the `register` function from `@teamhanko/hanko-elements` in the component where you want to use the
Hanko custom element. Call `register` to register the `<hanko-auth>` element with the browser's
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry).
Then use the `<hanko-auth>` element in your JSX.
To provide a login interface in your app, use the `<hanko-auth>` web component. To do so, first import the `register`
function from `@teamhanko/hanko-elements` in your React component. Then call `register` to register the `<hanko-auth>`
element with the browser's [`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry)
and use the `<hanko-auth>` element in your JSX.
:::info
@ -35,11 +37,9 @@ If you are self-hosting you need to provide the URL of your running Hanko backen
```jsx title="HankoAuth.jsx" showLineNumbers
import { register } from "@teamhanko/hanko-elements";
const api = process.env.REACT_APP_HANKO_API;
const lang = process.env.REACT_APP_HANKO_LANG;
const hankoApi = "<YOUR_API_URL>";
export default function HankoAuth() {
useEffect(() => {
// register the component
// see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
@ -50,30 +50,31 @@ export default function HankoAuth() {
}, []);
return (
<hanko-auth api={api} lang={lang} />
<hanko-auth api={hankoApi} />
);
}
```
## Defining login callbacks
### Define login callbacks
The `<hanko-auth>` element dispatches a custom `hankoAuthSuccess` event on successful login. React to this
event in order to, for example, redirect your users to protected pages in your application.
event in order to, for example, redirect your users to protected pages in your application,
e.g. a [user profile page](#hanko-profile).
To do so, apply an event listener with an appropriate redirect callback:
```jsx {2,9-20} title="HankoAuth.jsx" showLineNumbers
```jsx {2,10-19} title="HankoAuth.jsx" showLineNumbers
import React, { useEffect, useCallback } from "react";
import { useNavigate } from "react-router-dom";
import { register } from "@teamhanko/hanko-elements";
const api = process.env.REACT_APP_HANKO_API;
const lang = process.env.REACT_APP_HANKO_LANG;
const hankoApi = "<YOUR_API_URL>";
export default function HankoAuth() {
const navigate = useNavigate();
const redirectAfterLogin = useCallback(() => {
// successfully logged in, redirect to a page in your application
navigate("...", { replace: true });
}, [navigate]);
@ -93,16 +94,54 @@ export default function HankoAuth() {
}, []);
return (
<hanko-auth api={api} lang={lang} />
<hanko-auth api={hankoApi} />
);
}
```
## UI customization
## Add `<hanko-profile>` component {#hanko-profile}
The styles of the `hanko-auth` element can be customized using CSS variables and parts. See our guide
on customization [here](https://github.com/teamhanko/hanko/tree/main/frontend/elements#ui-customization).
To provide a page where users can manage their email addresses, password and passkeys, use the `<hanko-profile>` web
component. Just as with the `<hanko-auth>` component, import the `register` function from `@teamhanko/hanko-elements` in
your React component. Then call `register` to register the `<hanko-profile>` element with the browser's
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry) and use
the element in your JSX.
## Backend request authentication
:::info
When adding the `<hanko-profile>` element to your template you must provide the URL of the Hanko API via the `api`
attribute. If you are using [Hanko Cloud](https://cloud.hanko.io), you can find the API URL on your project dashboard.
If you are self-hosting you need to provide the URL of your running Hanko backend.
:::
```jsx title="HankoProfile.jsx" showLineNumbers
import { useEffect } from "react";
import { register } from "@teamhanko/hanko-elements";
const hankoApi = "<YOUR_API_URL>";
export default function HankoProfile() {
useEffect(() => {
// register the component
// see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
register({ shadow: true })
.catch((error) => {
// handle error
});
}, []);
return (
<hanko-profile api={hankoApi} />
);
};
```
## Customize component styles
The styles of the `hanko-auth` and `hanko-profile` elements can be customized using CSS variables and parts. See our
guide on customization [here](https://github.com/teamhanko/hanko/tree/main/frontend/elements#ui-customization).
## Authenticate backend requests
If you want to authenticate requests in your own backend, please view our [backend guide](/guides/backend).

View File

@ -11,7 +11,9 @@ sidebar_custom_props:
# Svelte
In this guide you will learn how to add authentication to your Svelte application using the Hanko custom element.
In this guide you will learn how to use the
[hanko-elements](https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md) web components to
add authentication and a user profile to your Svelte application.
## Install dependencies
Install the `@teamhanko/hanko-elements` package:
@ -20,12 +22,12 @@ Install the `@teamhanko/hanko-elements` package:
npm install @teamhanko/hanko-elements
```
## Import & use custom element
## Add `<hanko-auth>` component
Import the `register` function from `@teamhanko/hanko-elements` in the component where you want to use the
Hanko custom element. Call `register` to register the `<hanko-auth>` element with the browser's
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry).
Then use the `<hanko-auth>` element in your component template.
To provide a login interface in your app, use the `<hanko-auth>` web component. To do so, first import the `register`
function from `@teamhanko/hanko-elements` in your Svelte component. Then call `register` to register the `<hanko-auth>`
element with the browser's [`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry)
and use the `<hanko-auth>` element in your component.
:::info
@ -35,56 +37,55 @@ If you are self-hosting you need to provide the URL of your running Hanko backen
:::
```js title="Login.svelte" showLineNumbers
```js title="HankoAuth.svelte" showLineNumbers
<script>
import { onMount } from "svelte";
import { register } from '@teamhanko/hanko-elements';
const api = import.meta.env.VITE_HANKO_API;
const lang = import.meta.env.VITE_HANKO_LANG;
const hankoApi = "<YOUR_API_URL>";
onMount(async () => {
// register the component
// see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
register({ shadow: true }).catch((e) => {
console.error(e)
register({ shadow: true })
.catch((error) => {
// handle error
});
});
</script>
<div class="content">
<hanko-auth {api} {lang}/>
</div>
<hanko-auth api={hankoApi} />
```
## Defining login callbacks
### Define login callbacks
The `<hanko-auth>` element dispatches a custom `hankoAuthSuccess` event on successful login. React to this
event in order to, for example, redirect your users to protected pages in your application.
event in order to, for example, redirect your users to protected pages in your application,
e.g. a [user profile page](#hanko-profile).
To do so, apply an event listener with an appropriate redirect callback:
```js {2-3,9-14,23,26-28,32} title="Login.svelte" showLineNumbers
```js {2-3,7-13,23,26-28,31} title="HankoAuth.svelte" showLineNumbers
<script>
import { onDestroy, onMount } from "svelte";
import { useNavigate } from "svelte-navigator";
import { register } from '@teamhanko/hanko-elements';
const api = import.meta.env.VITE_HANKO_API;
const lang = import.meta.env.VITE_HANKO_LANG;
const hankoApi = "<YOUR_API_URL>";
const navigate = useNavigate();
let element;
const redirectToTodos = () => {
navigate('/todo');
const redirectAfterLogin = () => {
// successfully logged in, redirect to a page in your application
navigate('...');
};
onMount(async () => {
// register the component
// see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
register({ shadow: true }).catch((e) => {
console.error(e)
register({ shadow: true })
.catch((error) => {
// handle error
});
element.addEventListener('hankoAuthSuccess', redirectToTodos);
@ -95,16 +96,49 @@ To do so, apply an event listener with an appropriate redirect callback:
});
</script>
<div class="content">
<hanko-auth bind:this={element} {api} {lang}/>
</div>
<hanko-auth bind:this={element} api={hankoApi} />
```
## UI customization
## Add `<hanko-profile>` component {#hanko-profile}
The styles of the `hanko-auth` element can be customized using CSS variables and parts. See our guide
To provide a page where users can manage their email addresses, password and passkeys, use the `<hanko-profile>` web
component. Just as with the `<hanko-auth>` component, import the `register` function from `@teamhanko/hanko-elements` in
your Svelte component. Then call `register` to register the `<hanko-profile>` element with the browser's
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry) and use
the element in your component.
:::info
When adding the `<hanko-profile>` element to your template you must provide the URL of the Hanko API via the `api`
attribute. If you are using [Hanko Cloud](https://cloud.hanko.io), you can find the API URL on your project dashboard.
If you are self-hosting you need to provide the URL of your running Hanko backend.
:::
```js title="HankoProfile.svelte" showLineNumbers
<script>
import { register } from "@teamhanko/hanko-elements";
const hankoApi = "<YOUR_API_URL>";
onMount(async () => {
// register the component
// see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
register({ shadow: true })
.catch((error) => {
// handle error
});
});
</script>
<hanko-profile api={hankoApi}/>
```
## Customize component styles
The styles of the `hanko-auth` and `hanko-profile` elements can be customized using CSS variables and parts. See our guide
on customization [here](https://github.com/teamhanko/hanko/tree/main/frontend/elements#ui-customization).
## Backend request authentication
## Authenticate backend requests
If you want to authenticate requests in your own backend, please view our [backend guide](/guides/backend).

View File

@ -11,8 +11,9 @@ import TabItem from '@theme/TabItem';
# Vue
In this guide you will learn how to add authentication to your Vue application using the Hanko custom element.
In this guide you will learn how to use the
[hanko-elements](https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md) web components to
add authentication and a user profile to your Vue application.
## Install dependencies
Install the `@teamhanko/hanko-elements` package:
@ -21,11 +22,12 @@ Install the `@teamhanko/hanko-elements` package:
npm install @teamhanko/hanko-elements
```
## Register custom element with Vue
## Configure component resolution
Vue needs to know which elements to treat as custom elements, otherwise it will issue a warning regarding component
resolution. To do so, provide a predicate function that determines which elements are to be considered custom elements
to `compilerOptions.isCustomElement` in your configuration:
to [`compilerOptions.isCustomElement`](https://vuejs.org/guide/extras/web-components.html#using-custom-elements-in-vue)
in your configuration:
```mdx-code-block
<Tabs>
@ -40,7 +42,7 @@ export default {
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => tag === "hanko-auth"
isCustomElement: (tag) => tag.startsWith("hanko-")
}
}
})
@ -62,7 +64,7 @@ module.exports = {
.tap(options => ({
...options,
compilerOptions: {
isCustomElement: (tag) => tag === "hanko-auth"
isCustomElement: (tag) => tag.startsWith("hanko-")
}
}))
}
@ -74,11 +76,12 @@ module.exports = {
</Tabs>
```
## Import & use custom element
## Add `<hanko-auth>` component
Import the `register` function from `@teamhanko/hanko-elements` in the component where you want to use the
Hanko custom element. Call `register` to register the `<hanko-auth>` element with the browser's
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry). Then use the
To provide a login interface in your app, use the `<hanko-auth>` web component. To do so, first import the
`register` function from `@teamhanko/hanko-elements` in your Vue component. Then call `register` to register the
`<hanko-auth>` element with the browser's
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry) and use the
element in your component template.
:::info
@ -94,8 +97,7 @@ If you are self-hosting you need to provide the URL of your running Hanko backen
import { onMounted } from "vue";
import { register } from "@teamhanko/hanko-elements";
const api = import.meta.env.VITE_HANKO_API;
const lang = import.meta.env.VITE_HANKO_LANG;
const hankoApi = "<YOUR_API_URL>";
onMounted(() => {
// register the component
@ -105,30 +107,29 @@ onMounted(() => {
// handle error
});
});
</script>
<template>
<hanko-auth :api="api" :lang="lang" />
<hanko-auth :api="hankoApi" />
</template>
```
## Defining login callbacks
### Define login callbacks
The `<hanko-auth>` element dispatches a custom `hankoAuthSuccess` event on successful login. React to this
event in order to, for example, redirect your users to protected pages in your application.
event in order to, for example, redirect your users to protected pages in your application,
e.g. a [user profile page](#hanko-profile).
To do so, you can use Vue's [`v-on`](https://vuejs.org/guide/essentials/event-handling.html#listening-to-events)
directive (shorthand: `@`) and supply a callback directly on the `<hanko-auth>` element:
```js {2,18-23,27} title="HankoAuth.vue" showLineNumbers
```js {2,17-22,26} title="HankoAuth.vue" showLineNumbers
<script setup>
import { useRouter } from "vue-router";
import { onMounted } from "vue";
import { register } from "@teamhanko/hanko-elements";
const api = import.meta.env.VITE_HANKO_API;
const lang = import.meta.env.VITE_HANKO_LANG;
const hankoApi = "<YOUR_API_URL>";
onMounted(() => {
// register the component
@ -148,15 +149,54 @@ const redirectAfterLogin = () => {
</script>
<template>
<hanko-auth @hankoAuthSuccess="redirectAfterLogin" :api="api" :lang="lang" />
<hanko-auth @hankoAuthSuccess="redirectAfterLogin" :api="hankoApi" />
</template>
```
## UI customization
## Add `<hanko-profile>` component {#hanko-profile}
The styles of the `hanko-auth` element can be customized using CSS variables and parts. See our guide
To provide a page where users can manage their email addresses, password and passkeys, use the `<hanko-profile>` web
component. Just as with the `<hanko-auth>` component, import the `register` function from `@teamhanko/hanko-elements` in
your Vue component. Then call `register` to register the `<hanko-profile>` element with the browser's
[`CustomElementRegistry`](https://developer.mozilla.org/de/docs/Web/API/CustomElementRegistry) and use
the element in your component.
:::info
When adding the `<hanko-profile>` element to your template you must provide the URL of the Hanko API via the `api`
attribute. If you are using [Hanko Cloud](https://cloud.hanko.io), you can find the API URL on your project dashboard.
If you are self-hosting you need to provide the URL of your running Hanko backend.
:::
```js title="HankoProfile.vue" showLineNumbers
<script setup>
import { onMounted } from "vue";
import { register } from "@teamhanko/hanko-elements";
const hankoApi = "<YOUR_API_URL>";
onMounted(() => {
// register the component
// see: https://github.com/teamhanko/hanko/blob/main/frontend/elements/README.md#script
register({ shadow: true })
.catch((error) => {
// handle error
});
});
</script>
<template>
<hanko-profile :api="hankoApi" />
</template>
```
## Customize component styles
The styles of the `hanko-auth` and `hanko-profile` can be customized using CSS variables and parts. See our guide
on customization [here](https://github.com/teamhanko/hanko/tree/main/frontend/elements#ui-customization).
## Backend request authentication
## Authenticate backend requests
If you want to authenticate requests in your own backend, please view our [backend guide](/guides/backend).

9840
docs/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -15,8 +15,8 @@
"typecheck": "tsc"
},
"dependencies": {
"@docusaurus/core": "^2.2.0",
"@docusaurus/preset-classic": "^2.2.0",
"@docusaurus/core": "^2.3.1",
"@docusaurus/preset-classic": "^2.3.1",
"@docusaurus/remark-plugin-npm2yarn": "^2.2.0",
"@mdx-js/react": "^1.6.22",
"clsx": "^1.2.1",

View File

@ -398,7 +398,7 @@
<p class="tag-source">
<a href="lib_client_HttpClient.ts.html" class="button">View Source</a>
<span>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line241">line 241</a>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line265">line 265</a>
</span>
</p>

View File

@ -326,6 +326,290 @@ we can easily return to the fetch API.</div>
<h4 class="name" id="_getAuthCookie">
<a class="href-link" href="#_getAuthCookie">#</a>
<span class="code-name">
_getAuthCookie<span class="signature">()</span><span class="type-signature"> &rarr; {string|string}</span>
</span>
</h4>
<div class="description">
Returns the authentication token that was stored in the cookie.
</div>
<dl class="details">
<p class="tag-source">
<a href="lib_client_HttpClient.ts.html" class="button">View Source</a>
<span>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line289">line 289</a>
</span>
</p>
</dl>
<div class='columns method-parameter'>
<div class="column is-2"><label>Returns:</label></div>
<div class="column is-10">
<div class="columns">
<div class='column is-5 has-text-left'>
<label>Type: </label>
<code class="param-type">string</code>
</div>
</div>
<div class="columns">
<div class='column is-5 has-text-left'>
<label>Type: </label>
<code class="param-type">string</code>
</div>
</div>
</div>
</div>
</div>
<div class="member">
<h4 class="name" id="_setAuthCookie">
<a class="href-link" href="#_setAuthCookie">#</a>
<span class="code-name">
_setAuthCookie<span class="signature">(token)</span><span class="type-signature"></span>
</span>
</h4>
<div class="description">
Stores the authentication token to the cookie.
</div>
<h5>Parameters:</h5>
<div class="table-container">
<table class="params table">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr class="deep-level-0">
<td class="name"><code>token</code></td>
<td class="type">
<code class="param-type">string</code>
</td>
<td class="description last">The authentication token to be stored.</td>
</tr>
</tbody>
</table>
</div>
<dl class="details">
<p class="tag-source">
<a href="lib_client_HttpClient.ts.html" class="button">View Source</a>
<span>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line296">line 296</a>
</span>
</p>
</dl>
</div>
<div class="member">
<h4 class="name" id="delete">
<a class="href-link" href="#delete">#</a>
@ -442,7 +726,7 @@ we can easily return to the fetch API.</div>
<p class="tag-source">
<a href="lib_client_HttpClient.ts.html" class="button">View Source</a>
<span>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line310">line 310</a>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line356">line 356</a>
</span>
</p>
@ -650,7 +934,7 @@ we can easily return to the fetch API.</div>
<p class="tag-source">
<a href="lib_client_HttpClient.ts.html" class="button">View Source</a>
<span>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line267">line 267</a>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line313">line 313</a>
</span>
</p>
@ -903,7 +1187,7 @@ we can easily return to the fetch API.</div>
<p class="tag-source">
<a href="lib_client_HttpClient.ts.html" class="button">View Source</a>
<span>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line300">line 300</a>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line346">line 346</a>
</span>
</p>
@ -1156,7 +1440,7 @@ we can easily return to the fetch API.</div>
<p class="tag-source">
<a href="lib_client_HttpClient.ts.html" class="button">View Source</a>
<span>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line278">line 278</a>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line324">line 324</a>
</span>
</p>
@ -1409,7 +1693,7 @@ we can easily return to the fetch API.</div>
<p class="tag-source">
<a href="lib_client_HttpClient.ts.html" class="button">View Source</a>
<span>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line289">line 289</a>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line335">line 335</a>
</span>
</p>
@ -1494,6 +1778,154 @@ we can easily return to the fetch API.</div>
</div>
<div class="member">
<h4 class="name" id="removeAuthCookie">
<a class="href-link" href="#removeAuthCookie">#</a>
<span class="code-name">
removeAuthCookie<span class="signature">(token)</span><span class="type-signature"></span>
</span>
</h4>
<div class="description">
Removes the cookie used for authentication.
</div>
<h5>Parameters:</h5>
<div class="table-container">
<table class="params table">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th class="last">Description</th>
</tr>
</thead>
<tbody>
<tr class="deep-level-0">
<td class="name"><code>token</code></td>
<td class="type">
<code class="param-type">string</code>
</td>
<td class="description last">The authorization token to be stored.</td>
</tr>
</tbody>
</table>
</div>
<dl class="details">
<p class="tag-source">
<a href="lib_client_HttpClient.ts.html" class="button">View Source</a>
<span>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line303">line 303</a>
</span>
</p>
</dl>
</div>

View File

@ -719,7 +719,7 @@
<p class="tag-source">
<a href="lib_client_HttpClient.ts.html" class="button">View Source</a>
<span>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line249">line 249</a>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line273">line 273</a>
</span>
</p>
@ -839,7 +839,7 @@
<p class="tag-source">
<a href="lib_client_HttpClient.ts.html" class="button">View Source</a>
<span>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line256">line 256</a>
<a href="lib_client_HttpClient.ts.html">lib/client/HttpClient.ts</a>, <a href="lib_client_HttpClient.ts.html#line280">line 280</a>
</span>
</p>

View File

@ -448,7 +448,7 @@ occurred, you may want to prompt the user to log in.
<p class="tag-source">
<a href="lib_client_UserClient.ts.html" class="button">View Source</a>
<span>
<a href="lib_client_UserClient.ts.html">lib/client/UserClient.ts</a>, <a href="lib_client_UserClient.ts.html#line122">line 122</a>
<a href="lib_client_UserClient.ts.html">lib/client/UserClient.ts</a>, <a href="lib_client_UserClient.ts.html#line142">line 142</a>
</span>
</p>
@ -633,7 +633,7 @@ occurred, you may want to prompt the user to log in.
<p class="tag-source">
<a href="lib_client_UserClient.ts.html" class="button">View Source</a>
<span>
<a href="lib_client_UserClient.ts.html">lib/client/UserClient.ts</a>, <a href="lib_client_UserClient.ts.html#line135">line 135</a>
<a href="lib_client_UserClient.ts.html">lib/client/UserClient.ts</a>, <a href="lib_client_UserClient.ts.html#line155">line 155</a>
</span>
</p>
@ -869,7 +869,7 @@ want to log in with a passcode, or if no WebAuthn credentials are registered, yo
<p class="tag-source">
<a href="lib_client_UserClient.ts.html" class="button">View Source</a>
<span>
<a href="lib_client_UserClient.ts.html">lib/client/UserClient.ts</a>, <a href="lib_client_UserClient.ts.html#line108">line 108</a>
<a href="lib_client_UserClient.ts.html">lib/client/UserClient.ts</a>, <a href="lib_client_UserClient.ts.html#line128">line 128</a>
</span>
</p>
@ -970,6 +970,152 @@ want to log in with a passcode, or if no WebAuthn credentials are registered, yo
</div>
<div class="member">
<h4 class="name" id="logout">
<a class="href-link" href="#logout">#</a>
<span class='tag'>async</span>
<span class="code-name">
logout<span class="signature">()</span><span class="type-signature"> &rarr; {Promise.&lt;void>}</span>
</span>
</h4>
<div class="description">
Logs out the current user and expires the existing session cookie. A valid session cookie is required to call the logout endpoint.
</div>
<dl class="details">
<p class="tag-source">
<a href="lib_client_UserClient.ts.html" class="button">View Source</a>
<span>
<a href="lib_client_UserClient.ts.html">lib/client/UserClient.ts</a>, <a href="lib_client_UserClient.ts.html#line164">line 164</a>
</span>
</p>
</dl>
<div class='columns method-parameter'>
<div class="column is-2"><label>Throws:</label></div>
<div class="column is-10">
<div class="columns">
<div class='column is-12 has-text-left'>
<label>Type: </label>
<code class="param-type"><a href="TechnicalError.html">TechnicalError</a></code>
</div>
</div>
</div>
</div>
<div class='columns method-parameter'>
<div class="column is-2"><label>Returns:</label></div>
<div class="column is-10">
<div class="columns">
<div class='column is-5 has-text-left'>
<label>Type: </label>
<code class="param-type">Promise.&lt;void></code>
</div>
</div>
</div>
</div>
</div>
</div>

View File

@ -206,6 +206,7 @@ class Response {
class HttpClient {
timeout: number;
api: string;
authCookieName = "hanko";
// eslint-disable-next-line require-jsdoc
constructor(api: string, timeout = 13000) {
@ -215,11 +216,10 @@ class HttpClient {
// eslint-disable-next-line require-jsdoc
_fetch(path: string, options: RequestInit, xhr = new XMLHttpRequest()) {
const api = this.api;
const url = api + path;
const self = this;
const url = this.api + path;
const timeout = this.timeout;
const cookieName = "hanko";
const bearerToken = Cookies.get(cookieName);
const bearerToken = this._getAuthCookie();
return new Promise&lt;Response>(function (resolve, reject) {
xhr.open(options.method, url, true);
@ -240,11 +240,7 @@ class HttpClient {
if (headers.length) {
const authToken = xhr.getResponseHeader("X-Auth-Token");
if (authToken) {
const secure = !!api.match("^https://");
Cookies.set(cookieName, authToken, { secure });
}
if (authToken) self._setAuthCookie(authToken);
}
resolve(new Response(xhr));
@ -262,6 +258,35 @@ class HttpClient {
});
}
/**
* Returns the authentication token that was stored in the cookie.
*
* @return {string}
* @return {string}
*/
_getAuthCookie(): string {
return Cookies.get(this.authCookieName);
}
/**
* Stores the authentication token to the cookie.
*
* @param {string} token - The authentication token to be stored.
*/
_setAuthCookie(token: string) {
const secure = !!this.api.match("^https://");
Cookies.set(this.authCookieName, token, { secure });
}
/**
* Removes the cookie used for authentication.
*
* @param {string} token - The authorization token to be stored.
*/
removeAuthCookie() {
Cookies.remove(this.authCookieName);
}
/**
* Performs a GET request.
*

View File

@ -93,6 +93,7 @@ import {
UnauthorizedError,
} from "../Errors";
import { Client } from "./Client";
import Cookies from "js-cookie";
/**
* A class to manage user information.
@ -187,6 +188,27 @@ class UserClient extends Client {
return userResponse.json();
}
/**
* Logs out the current user and expires the existing session cookie. A valid session cookie is required to call the logout endpoint.
*
* @return {Promise&lt;void>}
* @throws {TechnicalError}
*/
async logout(): Promise&lt;void> {
const logoutResponse = await this.client.post("/logout");
// For cross-domain operations, the frontend SDK creates the cookie by reading the "X-Auth-Token" header, and
// "Set-Cookie" headers sent by the backend have no effect due to the browser's security policy, which means that
// the cookie must also be removed client-side in that case.
this.client.removeAuthCookie();
if (logoutResponse.status === 401) {
return; // The user is logged out already
} else if (!logoutResponse.ok) {
throw new TechnicalError();
}
}
}
export { UserClient };

View File

@ -713,6 +713,23 @@ paths:
$ref: '#/components/responses/Unauthorized'
'500':
$ref: '#/components/responses/InternalServerError'
/logout:
post:
summary: "Log out the current user"
description: "Logs out the user by removing the authorization cookie."
operationId: logout
tags:
- User Management
security:
- CookieAuth: [ ]
- BearerTokenAuth: [ ]
responses:
'204':
description: 'The user has been logged out'
'401':
$ref: '#/components/responses/Unauthorized'
'500':
$ref: '#/components/responses/InternalServerError'
/users:
post:
summary: 'Create a user'