Event are generated and delivered to your hooks. You will be notified when important events such as new user signup happen.
Events are divided into two kinds, Blocking and Non-blocking.
Each event can have multiple hooks. The delivery order of non-blocking events is unspecified. Blocking events are delivered in the order as in the configuration.
Blocking events are triggered before the operation is performed, such as before user creation. The operation can be aborted by your hooks.
They are delivered to your hooks synchronously, right before changes are persisted to the database.
Your hooks must return a JSON document to indicate whether the operation should continue.
To let the operation proceed, return a JSON document with is_allowed
set to true
.
{
"is_allowed": true
}
To abort the operation, return a JSON document with is_allowed
set to false
, and a non-empty reason
and title
.
{
"is_allowed": false,
"reason": "some reason",
"title": "some title"
}
If any of your hooks aborts the operation, the operation is aborted. The reason
and title
will be shown to the end-user as an error message.
Each of your hooks must respond within 5 seconds. All of your hooks must complete within 10 seconds. Otherwise, the delivery will fail to due timeout.
Your hooks can optionally apply mutation for certain blocking events. The supported mutation is specific for each type of blocking events. Refer to the Event List to see what mutation is supported.
Mutations by a hook is applied only when the operation is allowed to proceed. Mutations take effect only when all hooks allow the operation to proceed.
The mutations are specified in the hook response. Objects not appearing in mutations
are left intact. The mutated objects are NOT merged with the original ones.
The mutated objects are NOT validated, and are propagated along the hook chain. The mutated objects are validated after traversing the hook chain.
Mutations do NOT generate extra events to avoid infinite loops.
When a blocking event supports mutations on the user object, your hooks can respond a JSON document to allow the operation, and specify the mutations you want to apply on the user object.
{
"is_allowed": true,
"mutations": {
"user": {
"standard_attributes": {
"name": "John"
},
"custom_attributes": {
"age": 30
}
}
}
}
To mutate the user object, include user
inside mutations
. Only standard_attributes
and custom_attributes
of the user object are mutable.
You must include the WHOLE
standard_attributes
orcustom_attributes
when you specify the mutations. Otherwise, missing attributes WILL BE deleted.
When a blocking event supports mutations on the JWT payload, your hooks can respond a JSON document to allow the operation, and specify additional fields that you want to include in the JWT payload. However, you MUST NOT change or remove any existing fields in the JWT payload, as they are essential to the validity of the JWT.
{
"is_allowed": true,
"mutations": {
"jwt": {
"payload": {
// The original payload you get from the event object.
"iss": "https://myapp.authgear.cloud",
"aud": ["YOUR_CLIENT_ID"],
"sub": "THE_USER_ID",
// Other essential JWT fields that you MUST retain.
// Additional fields that you want to add.
"https://myapp.com": {
"custom_field": "custom_value"
}
}
}
}
}
To add additional fields to the JWT payload, include jwt.payload
inside mutations
. You MUST add your own fields only.
You must include the WHOLE
jwt.payload
from the event object when you specify the mutations.
Non-blocking events are triggered after the operation is performed.
They are delivered to your hooks asynchronously after the operation is performed.
Your hooks must finish within 60 seconds. Otherwise, the delivery will fail to due timeout.
The response of your hooks is ignored.
Events have the following shape:
{
"id": "0E1E9537-DF4F-4AF6-8B48-3DB4574D4F24",
"seq": 435,
"type": "user.pre_create",
"payload": { /* ... */ },
"context": {
"timestamp": 1670570552,
"user_id": "f333b70b-4436-4efb-a40b-d9ed7a74d319",
"preferred_languages": ["en-US", "zh-HK"],
"language": "en-US",
"triggered_by": "user"
}
}
id
: The ID of the event.
seq
: A monotonically increasing signed 64-bit integer.
type
: The type of the event.
payload
: The payload of the event, varies with type.
context
: The context of the event.
context.timestamp
: signed 64-bit UNIX timestamp of when this event is generated. Retried deliveries do not affect this field.
context.user_id
: The ID of the user associated with the event. It may be absent. For example, the user has not been authenticated yet.
context.preferred_languages
: User preferred languages, which are inferred from the request. Return values of the ui_locales
query if it is provided in the Auth UI, otherwise return languages in the Accept-Language
request header.
context.language
: User locale which is derived based on user's preferred languages and app's languages config.
context.triggered_by
: Triggered by indicates who triggered the events, values can be user
or admin_api
. user
means it is triggered by the end-user. admin_api
means it is triggered by Admin API or admin portal.
The full list of events
Occurs right before the user creation. User can be created by user signup, user signup as an anonymous user, or created by the admin via the Portal or Admin API.
This event supports Mutations on the user object
{
"type": "user.pre_create",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"identities": [
{
"id": "239d585d-9b90-4148-9aa2-2e3131b5847a",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"email": "user@example.com",
"https://authgear.com/claims/login_id/key": "email",
"https://authgear.com/claims/login_id/original_value": "user@example.com",
"https://authgear.com/claims/login_id/type": "email",
"https://authgear.com/claims/login_id/value": "user@example.com"
}
}
]
}
}
Occurs right before the update of the user profile.
This event supports Mutations on the user object
{
"type": "user.profile.pre_update",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"name": "Chris",
"updated_at": 1136171045
}
}
}
}
Occurs right before account deletion is scheduled.
This event does not support mutations.
{
"type": "user.pre_schedule_deletion",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": true,
"is_deactivated": true,
"delete_at": "2022-09-30T15:18:19.040081Z",
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
}
}
}
Occurs right before the access token is issued. Use this event to add custom fields to the JWT access token.
This event supports Mutations on the JWT payload
{
"type": "oidc.jwt.pre_create",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": true,
"is_deactivated": true,
"delete_at": "2022-09-30T15:18:19.040081Z",
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"jwt": {
"payload": {
"iss": "https://myapp.authgear.cloud",
"aud": ["YOUR_CLIENT_ID"],
"sub": "338deafa-400b-4589-a922-2c92d670b757"
}
}
}
}
Occurs after a new user is created. User can be created by user signup, user signup as an anonymous user, or created by the admin via the Portal or Admin API.
{
"type": "user.created",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"identities": [
{
"id": "239d585d-9b90-4148-9aa2-2e3131b5847a",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"email": "user@example.com",
"https://authgear.com/claims/login_id/key": "email",
"https://authgear.com/claims/login_id/original_value": "user@example.com",
"https://authgear.com/claims/login_id/type": "email",
"https://authgear.com/claims/login_id/value": "user@example.com"
}
}
]
}
}
Occurs when the user profile is updated.
{
"type": "user.profile.updated",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"name": "Chris",
"updated_at": 1136171045
}
}
}
}
Occurs after the user logged in.
{
"type": "user.authenticated",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"session": {
"id": "6e6e5d9b-7f85-4a8f-a157-2de94694dfea",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "idp",
"amr": ["pwd"],
"lastAccessedAt": "2006-01-02T03:04:05.123456Z",
"createdByIP": "127.0.0.1",
"lastAccessedByIP": "127.0.0.1",
"lastAccessedByIPCountryCode": "",
"lastAccessedByIPEnglishCountryName": "",
"displayName": "Chrome 104.0.0"
}
}
}
Occurs when the user was disabled.
{
"type": "user.disabled",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": true,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
}
}
}
Occurs when the user was re-enabled.
{
"type": "user.reenabled",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
}
}
}
Occurs whenever an anonymous user is promoted to a normal user.
{
"type": "user.anonymous.promoted",
"payload": {
"anonymous_user": {
"id": "7a009f88-c636-4245-91ec-7b174dc6a1a1",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"user": {
"id": "7a009f88-c636-4245-91ec-7b174dc6a1a1",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"identities": [
{
"id": "1450234b-5e2c-4aa0-b400-f2d9d70a2f45",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"email": "user@example.com",
"https://authgear.com/claims/login_id/key": "email",
"https://authgear.com/claims/login_id/original_value": "user@example.com",
"https://authgear.com/claims/login_id/type": "email",
"https://authgear.com/claims/login_id/value": "user@example.com"
}
}
]
}
}
Occurs when an account deletion was scheduled.
{
"type": "user.deletion_scheduled",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": true,
"is_deactivated": true,
"delete_at": "2006-01-02T03:04:05.123456Z",
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
}
}
}
Occurs when an account deletion was unscheduled.
{
"type": "user.deletion_unscheduled",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
}
}
}
Occurs when the user was deleted.
{
"type": "user.deleted",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": false,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": false,
"standard_attributes": {
"email": "user@example.com",
"email_verified": false,
"updated_at": 1136171045
}
}
}
}
Occurs when a new email is added to an existing user. Email can be added by the user in the setting page, added by the admin through the Admin API or Portal.
{
"type": "identity.email.added",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"phone_number": "+447400123456",
"phone_number_verified": true,
"updated_at": 1136171045
}
},
"identity": {
"id": "a0c55481-147e-4a58-876e-10dffedfd5cd",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"email": "user@example.com",
"https://authgear.com/claims/login_id/key": "email",
"https://authgear.com/claims/login_id/original_value": "user@example.com",
"https://authgear.com/claims/login_id/type": "email",
"https://authgear.com/claims/login_id/value": "user@example.com"
}
}
}
}
Occurs when an email address is removed from an existing user. Email can be removed by the user in the setting page, removed by admin through admin API or Portal.
{
"type": "identity.email.removed",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"phone_number": "+447400123456",
"phone_number_verified": true,
"updated_at": 1136171045
}
},
"identity": {
"id": "239d585d-9b90-4148-9aa2-2e3131b5847a",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"email": "user@example.com",
"https://authgear.com/claims/login_id/key": "email",
"https://authgear.com/claims/login_id/original_value": "user@example.com",
"https://authgear.com/claims/login_id/type": "email",
"https://authgear.com/claims/login_id/value": "user@example.com"
}
}
}
}
Occurs when an email address is updated. Email can be updated by the user on the setting page.
{
"type": "identity.email.updated",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user3@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"new_identity": {
"id": "239d585d-9b90-4148-9aa2-2e3131b5847a",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"email": "user3@example.com",
"https://authgear.com/claims/login_id/key": "email",
"https://authgear.com/claims/login_id/original_value": "user3@example.com",
"https://authgear.com/claims/login_id/type": "email",
"https://authgear.com/claims/login_id/value": "user3@example.com"
}
},
"old_identity": {
"id": "239d585d-9b90-4148-9aa2-2e3131b5847a",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"email": "user@example.com",
"https://authgear.com/claims/login_id/key": "email",
"https://authgear.com/claims/login_id/original_value": "user@example.com",
"https://authgear.com/claims/login_id/type": "email",
"https://authgear.com/claims/login_id/value": "user@example.com"
}
}
}
}
Occurs when an email address is change from unverified to verified for an existing user. Email can be verified by the user in the setting page, mark verified by admin through admin API or Portal.
{
"type": "identity.email.verified",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"identity": {
"id": "239d585d-9b90-4148-9aa2-2e3131b5847a",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"email": "user@example.com",
"https://authgear.com/claims/login_id/key": "email",
"https://authgear.com/claims/login_id/type": "email",
"https://authgear.com/claims/login_id/value": "user@example.com"
}
}
}
}
Occurs when an email address is unverified. Email can be unverified using Admin API.
{
"type": "identity.email.unverified",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": false,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": false,
"updated_at": 1136171045
}
},
"identity": {
"id": "239d585d-9b90-4148-9aa2-2e3131b5847a",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"email": "user@example.com",
"https://authgear.com/claims/login_id/key": "email",
"https://authgear.com/claims/login_id/type": "email",
"https://authgear.com/claims/login_id/value": "user@example.com"
}
}
}
}
Occurs when a new phone number is added to an existing user. Phone numbers can be added by the user in the setting page, added by admin through admin API or Portal.
{
"type": "user.phone.added",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"phone_number": "+447400123456",
"phone_number_verified": true,
"updated_at": 1136171045
}
},
"identity": {
"id": "9fa5668d-a796-4817-93e1-d4096e5966ac",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"https://authgear.com/claims/login_id/key": "phone",
"https://authgear.com/claims/login_id/original_value": "+447400123456",
"https://authgear.com/claims/login_id/type": "phone",
"https://authgear.com/claims/login_id/value": "+447400123456",
"phone_number": "+447400123456"
}
}
}
}
Occurs when a phone number is removed from an existing user. Phone numbers can be removed by the user on the setting page, removed by admin through admin API or Portal.
{
"type": "identity.phone.removed",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"identity": {
"id": "9fa5668d-a796-4817-93e1-d4096e5966ac",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"https://authgear.com/claims/login_id/key": "phone",
"https://authgear.com/claims/login_id/original_value": "+447400123455",
"https://authgear.com/claims/login_id/type": "phone",
"https://authgear.com/claims/login_id/value": "+447400123455",
"phone_number": "+447400123455"
}
}
}
}
Occurs when a phone number is updated. Phone numbers can be updated by the user on the setting page.
{
"type": "identity.phone.updated",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"phone_number": "+447400123455",
"phone_number_verified": true,
"updated_at": 1136171045
}
},
"new_identity": {
"id": "9fa5668d-a796-4817-93e1-d4096e5966ac",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"https://authgear.com/claims/login_id/key": "phone",
"https://authgear.com/claims/login_id/original_value": "+447400123455",
"https://authgear.com/claims/login_id/type": "phone",
"https://authgear.com/claims/login_id/value": "+447400123455",
"phone_number": "+447400123455"
}
},
"old_identity": {
"id": "9fa5668d-a796-4817-93e1-d4096e5966ac",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"https://authgear.com/claims/login_id/key": "phone",
"https://authgear.com/claims/login_id/original_value": "+447400123456",
"https://authgear.com/claims/login_id/type": "phone",
"https://authgear.com/claims/login_id/value": "+447400123456",
"phone_number": "+447400123456"
}
}
}
}
Occurs when a phone number is change from unverified to verified for an existing user. Phone can be verified by the user in the setting page, mark verified by admin through admin API or Portal.
{
"type": "identity.phone.verified",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"phone_number": "+447400123455",
"phone_number_verified": true,
"updated_at": 1136171045
}
},
"identity": {
"id": "9fa5668d-a796-4817-93e1-d4096e5966ac",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"https://authgear.com/claims/login_id/key": "phone",
"https://authgear.com/claims/login_id/type": "phone",
"https://authgear.com/claims/login_id/value": "+447400123455",
"phone_number": "+447400123455"
}
}
}
}
Occurs when a phone number is unverified. Phone numbers can be unverified using Admin API.
{
"type": "identity.phone.unverified",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": false,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"phone_number": "+447400123455",
"phone_number_verified": false,
"updated_at": 1136171045
}
},
"identity": {
"id": "9fa5668d-a796-4817-93e1-d4096e5966ac",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"https://authgear.com/claims/login_id/key": "phone",
"https://authgear.com/claims/login_id/type": "phone",
"https://authgear.com/claims/login_id/value": "+447400123455",
"phone_number": "+447400123455"
}
}
}
}
Occurs when a new username is added to an existing user. Username can be added by the user in setting page, added by admin through Admin API or Portal.
{
"type": "identity.username.added",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"preferred_username": "user01",
"updated_at": 1136171045
}
},
"identity": {
"id": "38683500-f6ce-477d-b944-1f915a451995",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"https://authgear.com/claims/login_id/key": "username",
"https://authgear.com/claims/login_id/original_value": "user01",
"https://authgear.com/claims/login_id/type": "username",
"https://authgear.com/claims/login_id/value": "user01",
"preferred_username": "user01"
}
}
}
}
Occurs when the username is removed from an existing user. The username can be removed by the user on the setting page, removed by admin through admin API or Portal.
{
"type": "identity.username.removed",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"identity": {
"id": "38683500-f6ce-477d-b944-1f915a451995",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"https://authgear.com/claims/login_id/key": "username",
"https://authgear.com/claims/login_id/original_value": "user02",
"https://authgear.com/claims/login_id/type": "username",
"https://authgear.com/claims/login_id/value": "user02",
"preferred_username": "user02"
}
}
}
}
Occurs when the username is updated. The username can be updated by the user on the setting page.
{
"type": "identity.username.updated",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"preferred_username": "user02",
"updated_at": 1136171045
}
},
"new_identity": {
"id": "38683500-f6ce-477d-b944-1f915a451995",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"https://authgear.com/claims/login_id/key": "username",
"https://authgear.com/claims/login_id/original_value": "user02",
"https://authgear.com/claims/login_id/type": "username",
"https://authgear.com/claims/login_id/value": "user02",
"preferred_username": "user02"
}
},
"old_identity": {
"id": "38683500-f6ce-477d-b944-1f915a451995",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "login_id",
"claims": {
"https://authgear.com/claims/login_id/key": "username",
"https://authgear.com/claims/login_id/original_value": "user01",
"https://authgear.com/claims/login_id/type": "username",
"https://authgear.com/claims/login_id/value": "user01",
"preferred_username": "user01"
}
}
}
}
Occurs when a user has connected to a new OAuth provider.
{
"type": "identity.oauth.connected",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"identity": {
"id": "f22425cf-68b2-45f8-936d-3c54c9cdf5c7",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "oauth",
"claims": {
"email": "xxx@gmail.com",
"email_verified": true,
"family_name": "",
"given_name": "",
"https://authgear.com/claims/oauth/profile": {
"at_hash": "",
"aud": ["xxx.apps.googleusercontent.com"],
"azp": "xxx.apps.googleusercontent.com",
"email": "xxx@gmail.com",
"email_verified": true,
"exp": "2006-01-02T03:04:05Z",
"family_name": "",
"given_name": "",
"iat": "2006-01-02T03:04:05Z",
"iss": "https://accounts.google.com",
"locale": "en",
"name": "",
"nonce": "",
"picture": "https://lh3.googleusercontent.com/a/xxx",
"sub": ""
},
"https://authgear.com/claims/oauth/provider_alias": "google",
"https://authgear.com/claims/oauth/provider_type": "google",
"https://authgear.com/claims/oauth/subject_id": "",
"locale": "en",
"name": "",
"picture": "https://lh3.googleusercontent.com/a/xxx"
}
}
}
}
Occurs when a user is disconnected from an OAuth provider. It can be done by the user disconnecting their OAuth provider in the setting page, or the admin removing the OAuth identity through admin API or Portal.
{
"type": "identity.oauth.disconnected",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"identity": {
"id": "f22425cf-68b2-45f8-936d-3c54c9cdf5c7",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "oauth",
"claims": {
"email": "xxx@gmail.com",
"email_verified": true,
"family_name": "",
"given_name": "",
"https://authgear.com/claims/oauth/profile": {
"at_hash": "",
"aud": ["xxx.apps.googleusercontent.com"],
"azp": "xxx.apps.googleusercontent.com",
"email": "xxx@gmail.com",
"email_verified": true,
"exp": "2006-01-02T03:04:05Z",
"family_name": "",
"given_name": "",
"iat": "2006-01-02T03:04:05Z",
"iss": "https://accounts.google.com",
"locale": "en",
"name": "",
"nonce": "",
"picture": "https://lh3.googleusercontent.com/a/xxx",
"sub": ""
},
"https://authgear.com/claims/oauth/provider_alias": "google",
"https://authgear.com/claims/oauth/provider_type": "google",
"https://authgear.com/claims/oauth/subject_id": "",
"locale": "en",
"name": "",
"picture": "https://lh3.googleusercontent.com/a/xxx"
}
}
}
}
Occurs when the user enabled biometric login.
{
"type": "identity.biometric.enabled",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"identity": {
"id": "5cb77960-634b-4c0e-8a0e-6c2c73fb8f47",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "biometric",
"claims": {
"https://authgear.com/claims/biometric/device_info": {
"ios": {
"NSBundle": {
"CFBundleDisplayName": "Authgear demo iOS",
"CFBundleExecutable": "ios_example",
"CFBundleIdentifier": "com.authgear.exampleapp.ios",
"CFBundleName": "ios_example",
"CFBundleShortVersionString": "1.0",
"CFBundleVersion": "1653565975"
},
"NSProcessInfo": {
"isMacCatalystApp": false,
"isiOSAppOnMac": false
},
"UIDevice": {
"model": "iPhone",
"name": "iPhone",
"systemName": "iOS",
"systemVersion": "16.1.1",
"userInterfaceIdiom": "phone"
},
"uname": {
"machine": "iPhone13,3",
"nodename": "Users-iPhone",
"release": "22.1.0",
"sysname": "Darwin",
"version": "Darwin Kernel Version 22.1.0: Thu Oct 6 19:34:22 PDT 2022; root:xnu-8792.42.7~1/RELEASE_ARM64_T8101"
}
}
},
"https://authgear.com/claims/biometric/formatted_device_info": "iPhone 12 Pro",
"https://authgear.com/claims/biometric/key_id": "1CC9D95A-6578-4557-8279-C4D5699D3549"
}
}
}
}
Occurs when biometric login is disabled. It will be triggered only when the user disabled it from the settings page or the admin disabled it from the Admin API or portal.
{
"type": "identity.biometric.disabled",
"payload": {
"user": {
"id": "338deafa-400b-4589-a922-2c92d670b757",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"last_login_at": "2006-01-02T03:04:05.123456Z",
"is_anonymous": false,
"is_verified": true,
"is_disabled": false,
"is_deactivated": false,
"can_reauthenticate": true,
"standard_attributes": {
"email": "user@example.com",
"email_verified": true,
"updated_at": 1136171045
}
},
"identity": {
"id": "5cb77960-634b-4c0e-8a0e-6c2c73fb8f47",
"created_at": "2006-01-02T03:04:05.123456Z",
"updated_at": "2006-01-02T03:04:05.123456Z",
"type": "biometric",
"claims": {
"https://authgear.com/claims/biometric/device_info": {
"ios": {
"NSBundle": {
"CFBundleDisplayName": "Authgear demo iOS",
"CFBundleExecutable": "ios_example",
"CFBundleIdentifier": "com.authgear.exampleapp.ios",
"CFBundleName": "ios_example",
"CFBundleShortVersionString": "1.0",
"CFBundleVersion": "1653565975"
},
"NSProcessInfo": {
"isMacCatalystApp": false,
"isiOSAppOnMac": false
},
"UIDevice": {
"model": "iPhone",
"name": "iPhone",
"systemName": "iOS",
"systemVersion": "16.1.1",
"userInterfaceIdiom": "phone"
},
"uname": {
"machine": "iPhone13,3",
"nodename": "Users-iPhone",
"release": "22.1.0",
"sysname": "Darwin",
"version": "Darwin Kernel Version 22.1.0: Thu Oct 6 19:34:22 PDT 2022; root:xnu-8792.42.7~1/RELEASE_ARM64_T8101"
}
}
},
"https://authgear.com/claims/biometric/formatted_device_info": "iPhone 12 Pro",
"https://authgear.com/claims/biometric/key_id": "1CC9D95A-6578-4557-8279-C4D5699D3549"
}
}
}
}
The event may contain different objects. You can refer to the below for their attributes.
"payload":{
"user": {
"id": "string",
"created_at": "timestamp",
"updated_at": "timestamp",
"last_login_at": "timestamp",
"is_anonymous": boolean,
"is_verified": boolean,
"is_disabled": boolean,
"is_deactivated": boolean,
"can_reauthenticate": boolean,
"standard_attributes": {
...
},
"custom_attributes": {
...
}
}
}
Webhooks is one of the supported hooks to receive events.
To use webhooks you need to:
Deploy a webhook on your server.
Configure Authgear to deliver events to your webhook.
In the portal, go to Advanced > Hooks.
Add your webhooks in Blocking Events and Non-Blocking Events, depending on which event you want to listen to.
Click Save.
hook:
blocking_handlers:
- event: "user.pre_create"
url: 'https://myapp.com/check_user_create'
non_blocking_handlers:
# listen to all events and filter events by type in request
- events: ["*"]
url: 'https://myapp.com/all_events'
- events: ["user.created"]
url: 'https://myapp.com/sync_user_creation'
Events are delivered to your webhooks via HTTPS, so your server must support HTTPS.
Events are delivered to your webhooks with POST requests. You webhooks must return a HTTP status code within 2xx range. Other status codes are considered as a failed delivery.
The request to your webhooks is signed with a secret key shared between Authgear and your hooks. You are RECOMMENDED to verify the signature and reject any requests with invalid signatures. This ensures the request originates from Authgear.
The signature is calculated as the hex encoded value of HMAC-SHA256 of the request body and included in the HTTP header x-authgear-body-signature
.
To obtain the secret key, visit the portal and go to Advanced -> Hooks -> Webhook Signature. You may need to reauthenticate yourselves before you can reveal the secret key.
Here is the sample code of how to calculate the signature and verify it.
package main
import (
"crypto/hmac"
"crypto/sha256"
"crypto/subtle"
"encoding/hex"
"fmt"
"io"
"net/http"
)
// Obtain the secret in the portal.
const Secret = "SECRET"
// HMACSHA256String returns the hex-encoded string of HMAC-SHA256 code of body using secret as key.
func HMACSHA256String(data []byte, secret []byte) (sig string) {
hasher := hmac.New(sha256.New, secret)
_, _ = hasher.Write(data)
signature := hasher.Sum(nil)
sig = hex.EncodeToString(signature)
return
}
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
b, err := io.ReadAll(r.Body)
if err != nil {
// Handle the error properly
panic(err)
}
defer r.Body.Close()
sigInHeader := []byte(r.Header.Get("X-Authgear-Body-Signature"))
sig := []byte(HMACSHA256String(b, []byte(Secret)))
// Prefer constant time comparison over == operator.
if subtle.ConstantTimeCompare(sigInHeader, sig) != 1 {
// The signature does not match
// Do NOT trust the content of this webhook!!!
panic(fmt.Errorf("%v != %v", string(sigInHeader), string(sig)))
}
// Continue your logic here.
})
http.ListenAndServe(":9999", nil)
}
JavaScript / TypeScript Hooks is one of the supported hooks to receive events.
JavaScript / TypeScript Hooks are written as a ES2015 module. The module is executed by Deno.
The module MUST have a default export of a function taking 1 argument. The argument is the event. The function can either be synchronous or asynchronous.
If the Hook is registered for a blocking event, the function MUST return a value according to the specification.
The Hooks DO NOT have access to file, or environment. They only have access to external network.
The stdout and the stderr of the Hooks are both ignored. Your hooks MUST NOT assume anything on the arguments and the stdin of the module.
In the portal, go to Advanced > Hooks.
Add your Hooks in Blocking Events and Non-Blocking Events, depending on which event you want to listen to.
Click Save.
Here is an example of a Hook for a blocking event.
import { HookEvent, HookResponse } from "https://deno.land/x/authgear_deno_hook@v1.0.0/mod.ts";
export default async function(e: HookEvent): Promise<HookResponse> {
// This hook simply allows the operation, which is identical to no-op.
return { is_allowed: true };
}
An example to mutate a JWT token
import {HookResponse, EventOIDCJWTPreCreate } from "https://deno.land/x/authgear_deno_hook@v1.0.0/mod.ts";
export default async function(event: EventOIDCJWTPreCreate): Promise<HookResponse> {
return {
is_allowed: true,
mutations: {
jwt:{
payload:{
...event.payload.jwt.payload, //the original payload in the jwt
"https://myapp.com": {
"custom_field": "custom_value"
}
}
}
}
};
}
Here is an example of a Hook for a non-blocking event.
import { HookEvent } from "https://deno.land/x/authgear_deno_hook@v0.3.0/mod.ts";
export default async function(e: HookEvent): Promise<void> {
// This hook does nothing, which is identical to no-op.
}
https://deno.land/x/authgear_deno_hook is a TypeScript definition that aids you in writing a Hook. You can see the full definition at https://deno.land/x/authgear_deno_hook/mod.ts
If you are a Visual Studio Code user, you can set up your editor to take full advantage of the definition.
Alternatively, you can edit your hook and use the Deno CLI to typecheck.
$ deno check YOUR_HOOK.ts
Authgear Webhook is a feature that sends notifications in the form of HTTP requests to an external URL that you specify when certain events occur. For example, Webhook can send the user.pre_create event just before a new user is created.
Webhooks also listen for response from your external services. For blocking events, this response determines if the process that triggered the event should continue to completion or be terminated. In this post, we'll use a blocking event and a custom webhook endpoint to restrict user signup to only devices from inside a corporate network.
Configuring a webhook for the user.pre-created
event will prevent Authgear from creating new users if your webhook endpoint returns is_allowed: false
in its response. In contrast, a new user will be created successfully when the endpoint returns is_allowed: true
in its response.
We will be using this behavior to prevent users from outside a corporate network from signing up by checking their IP address (which is provided in the payload of the webhook HTTP request from Authgear). When the IP address matches a specified allowed IP address, we set the value for is_allowed
to true
. Otherwise, we return false
.
The following tutorial shows detailed steps for allowing signups from inside a corporate network only.
In this step, we'll create a webhook for the User pre-create event in the Authgear Portal. To do that, login to the Authgear Portal and navigate to Advance > Hooks. Next, under Blocking Events section, click on Add, then select Webhook as the type and User pre-create as the Event.
Enter the full URL that points to the page that will be receiving and processing the webhook requests in the Endpoint text field.
Once you're done, click on the Save button at the top.
You'll need to create an endpoint in your preferred programming language or framework and host it online. For this tutorial, we'll be creating a basic Express.js endpoint.
Create a new Express.js project and add the following code to app.js
:
const express = require("express");
const app = express();
const bodyParser = require('body-parser');
const port = process.env.PORT || 3002;
app.use(bodyParser.json());
app.post('/', (request, response) => {
response.status(200).send(
{
"is_allowed": false,
"reason": "some reason",
"title": "some title"
}
);
});
app.listen(port, () => {
console.log("server started!");
});
Let's walk through what the above code will do:
Express creates an endpoint that accepts POST requests. (Note that the Authgear webhook only sends POST HTTP requests and your endpoint must support HTTPS).
Deploying the above code and pointing your Authgear webhook endpoint to it should prevent any user from signing up.
This is because the code returns is_allowed: false
as a response to the Webhook. Hence terminating the signup process.
You can also state a more descriptive reason for termination in the endpoint response using the reason
field.
Authgear webhooks send data to the endpoint URL to enable developers to build custom features and more. In this step, we'll read the data from the User pre-created event call and get the IP address for the user trying to register.
To read the request body and output the value to the console add the following code to app.js on a new line just above response.status(200)...
const requestPayload = request.body;
console.log(requestPayload)
Attempting to register a new user again should print JSON data similar to this to your endpoints console:
{
id: '0000000000022b55',
seq: 142165,
type: 'user.pre_create',
payload: {
user: {
id: '413fe869-dba2-43a8-b671-95fd471b7950',
created_at: '2023-08-14T03:44:36.383367Z',
updated_at: '2023-08-14T03:44:36.473456Z',
is_anonymous: false,
is_verified: true,
is_disabled: false,
is_deactivated: false,
is_anonymized: false,
can_reauthenticate: true,
standard_attributes: [Object],
x_web3: [Object]
},
identities: [ [Object] ]
},
context: {
timestamp: 1691984676,
user_id: '413fe869-dba2-43a8-b671-95fd471b7950',
triggered_by: 'user',
audit_context: null,
preferred_languages: [ 'en-US', 'en' ],
language: 'en',
ip_address: '123.456.78.009',
user_agent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/116.0',
app_id: 'my_test_app'
}
}
The data we're interested in for this example is ip_address
in the context
object (context.ip_address). We'll use this IP address to determine whether a user is inside the corporate network.
Now, update app.js so that it returns is_allowed: true
when the user's IP address is within the corporate network's IP address.
The code for app.js should look like this after the modification:
app.post('/', (request, response) => {
const requestPayload = request.body;
console.log(requestPayload)
const allowedIp = '123.456.78.009'; //replace the value with the corporate network IP address
if (requestPayload.context.ip_address == $orgIp) {
//this user is from the organisation network, continue with sign up.
response.status(200).type('json').send(
{
"is_allowed": true
}
);
} else {
//user has an IP address outside of the organisation network so disallow sign up.
response.status(200).type('json').send(
{
"is_allowed": false,
"reason": "You are not allow to sign up to this organisation",
"title": "Sign-up not allowed!"
}
)
}
});
You should replace the value for allowedIp
with the IP address you wish to allow.
At this point, if you deploy your endpoint and try signing up from the allowed IP the process should complete without issue, and you've successfully implemented signups only from a corporate network.
Authgear offers an alternative for regular webhooks called the JavaScript/TypeScript hooks. This kind of hook makes it possible to implement our earlier solution without hosting an external endpoint. In the following section, we'll walk through the steps for allowing signups from inside a corporate network only using the Typescript hook.
Navigate to Advance > Hooks in the Authgear portal. Next, click on Add under the Blocking Events section. Or, modify the previous webhook.
Select TypeScript as the type and User pre-create as the Event.
The third field in a TypeScript hook is different from a regular webhook. The field allows you to enter JavaScript code that the hook can execute when an event is triggered.
You can click on the Edit Script button near the Script field to open the hook script editor.
Modify the code in the script editor to the following:
export default async function (e: EventUserPreCreate): Promise<HookResponse> {
// Write your hook with the help of the type definition.
const allowedIp = "123.456.78.009";
if (e.context.ip_address == allowedIp) {
return {
is_allowed: true,
};
} else {
return {
is_allowed: false,
reason: "You are not allow to sign up to this organisation",
title: "Sign-up not allowed!",
};
}
}
Make sure to update the value for allowedIp
to the IP address you wish to allow.
Once you're done, click on Finish Editing to return to the Hooks configuration page. Save your new hook by clicking on the Save button at the top of the configuration page.
To test that your TypeScript hook is working properly, try signing up a new user from the IP address you specified earlier. Also, try signing up outside that IP address to see if everything works as expected.