# Cloudflare Workers Reference

PropelAuth's Cloudflare Workers library provides all the building blocks you need to add authentication to your Cloudflare Workers projects.

## [Installation](https://docs.propelauth.com/reference/backend-apis/cloudflare-workers#installation)

```shell
npm install @propelauth/cloudflare-worker
```

## [Initialize](https://docs.propelauth.com/reference/backend-apis/cloudflare-workers#initialize)

`initAuth` performs a one-time initialization of the library.
It will verify your `apiKey` is correct and fetch the metadata needed to verify access tokens in [validateAccessTokenAndGetUserClass](https://docs.propelauth.com/reference/backend-apis/cloudflare-workers#protect-api-routes).

You can find the `authUrl`, `apiKey`, and `verifierKey` in the **Backend Integration** section in your PropelAuth dashboard.

```typescript
import { initAuth } from '@propelauth/cloudflare-worker'

const {
    validateAccessTokenAndGetUserClass,
    // ...
} = initAuth({
    authUrl: 'REPLACE_ME',
    apiKey: 'REPLACE_ME',
    verifierKey: 'REPLACE_ME',
})
```

## [Protect API Routes](https://docs.propelauth.com/reference/backend-apis/cloudflare-workers#protect-api-routes)

After initializing auth, you can verify access tokens by passing it in the Authorization header (formatted `Bearer TOKEN`) to `validateAccessTokenAndGetUserClass`.
You can see more information about the User Class [here](https://docs.propelauth.com/reference/backend-apis/cloudflare-workers#user-class).

```ts
const authorizationHeader = // Get the Authorization header from an HTTP request
try {
    const user = await validateAccessTokenAndGetUserClass(authorizationHeader)
    console.log(`Got request from user ${user.userId}`);
} catch (err) {
    // You can return a 401, or continue the request knowing it wasn't sent from a logged-in user
    console.log(`Unauthorized request ${err}`);
}
```

Verifying the access token doesn't require an external request.

## [Authorization / Organizations](https://docs.propelauth.com/reference/backend-apis/cloudflare-workers#authorization-organizations)

You can also verify which organizations the user is in, and which roles and permissions they have in each organization all through the [User Class](https://docs.propelauth.com/reference/backend-apis/cloudflare-workers#user-class)

### Check Org Membership

Verify that the request was made by a valid user **and** that the user is a member of the specified organization.

```ts
const authorizationHeader = // Get the Authorization header from an HTTP request
const orgId = // get the orgId from somewhere, such as the request URL
try {
    const user = await validateAccessTokenAndGetUserClass(authorizationHeader)
    const org = user.getOrg(orgId)
    if (!org) {
        // return a 403
    }
    console.log(`Got request from user ${user.userId} for org ${org.orgName}`);
} catch (err) {
    // You can return a 401, or continue the request knowing it wasn't sent from a logged-in user
    console.log(`Unauthorized request ${err}`);
}
```

### Check Org Membership and Role

Similar to checking org membership, but will also verify that the user has a specific Role in the organization.

A user has a Role within an organization. By default, the available roles are Owner, Admin, or Member, but these can be configured. These roles are also hierarchical, so Owner > Admin > Member.

```ts
const authorizationHeader = // Get the Authorization header from an HTTP request
const orgId = // get the orgId from somewhere, such as the request URL
try {
    const user = await validateAccessTokenAndGetUserClass(authorizationHeader)
    const org = user.getOrg(orgId)
    if (!org || !org.isRole("Admin")) {
        // return a 403
    }
    console.log(`Got request from Admin user ${user.userId} for org ${org.orgName}`);
} catch (err) {
    // You can return a 401, or continue the request knowing it wasn't sent from a logged-in user
    console.log(`Unauthorized request ${err}`);
}
```

### Check Org Membership and Permission

Similar to checking org membership, but will also verify that the user has the specified permission in the organization.

Permissions are arbitrary strings associated with a role. For example, `can_view_billing`, `ProductA::CanCreate`, and `ReadOnly` are all valid permissions. You can create these permissions in the PropelAuth dashboard.

```ts
const authorizationHeader = // Get the Authorization header from an HTTP request
const orgId = // get the orgId from somewhere, such as the request URL
try {
    const user = await validateAccessTokenAndGetUserClass(authorizationHeader)
    const org = user.getOrg(orgId)
    if (!org || !org.hasPermission("can_view_billing")) {
        // return a 403
    }
    console.log(`User ${user.userId} has 'can_view_billing' permissions for org ${org.orgName}`);
} catch (err) {
    // You can return a 401, or continue the request knowing it wasn't sent from a logged-in user
    console.log(`Unauthorized request ${err}`);
}
```

## [User Class](https://docs.propelauth.com/reference/backend-apis/cloudflare-workers#user-class)

The User Class contains information about the user that made the request. It also contains methods such as `getOrgs()` and `hasPermission()`.

```javascript
const userClass = await validateAccessTokenAndGetUserClass(authorizationHeader)
```

- **Name** `userId`
  - **Type** string
  - **Description** The unique id of the user.
- **Name** `orgIdToOrgMemberInfo`
  - **Type** {[orgId: string]: OrgMemberInfo}
  - **Description** A dictionary mapping from organization id to [OrgMemberInfo](https://docs.propelauth.com/reference/backend-apis/cloudflare-workers#org-member-info) object.
- **Name** `email`
  - **Type** string
  - **Description** The email of the user.
- **Name** `firstName`
  - **Type** string
  - **Description** The first name of the user.
- **Name** `lastName`
  - **Type** string
  - **Description** The last name of the user.
- **Name** `username`
  - **Type** string
  - **Description** The username of the user.
- **Name** `properties`
  - **Type** {[key: string]: unknown}
  - **Description** A dictionary of [custom properties](https://docs.propelauth.com/overview/user-management/user-properties#custom-user-properties) associated with the user.
- **Name** `loginMethod`
  - **Type** object
  - **Description** The method the user used to log in. Returns the [Login Method Property](https://docs.propelauth.com/overview/authentication/login-methods).
- **Name** `activeOrgId`
  - **Type** string | undefined
  - **Description** Returns the ID of the [Active Org](https://docs.propelauth.com/recipes/active-org), if the user has an Active Org set.
- **Name** `legacyUserId`
  - **Type** string
  - **Description** If the user was migrated using our [Migration API](https://docs.propelauth.com/migrations), this will be the id of the user in the legacy system.
- **Name** `impersonatorUserId`
  - **Type** string
  - **Description** If the user is being impersonated, this is id of the user that impersonated them.
- **Name** `getActiveOrg()`
  - **Type** fn() -> OrgMemberInfo
  - **Description** Returns the [OrgMemberInfo](https://docs.propelauth.com/reference/backend-apis/cloudflare-workers#org-member-info) of the [Active Org](https://docs.propelauth.com/recipes/active-org).
- **Name** `getOrg()`
  - **Type** fn(orgId: string) -> OrgMemberInfo
  - **Description** A method to retrieve [OrgMemberInfo](https://docs.propelauth.com/reference/backend-apis/cloudflare-workers#org-member-info) of the provided org. Returns undefined if user does not belong to org.
- **Name** `getOrgByName()`
  - **Type** fn(orgName: string) -> string
  - **Description** A method to retrieve the [OrgMemberInfo](https://docs.propelauth.com/reference/backend-apis/cloudflare-workers#org-member-info) of an org by name. Returns undefined if user does not belong to the provided org.
- **Name** `getUserProperty()`
  - **Type** fn(key: string)
  - **Description** A method to retrieve the value of the provided property for the user. Returns undefined if no value is set.
- **Name** `getOrgs()`
  - **Type** fn() -> OrgMemberInfo[]
  - **Description** A method to retrieve an array of each org the user belongs to.
- **Name** `isImpersonating()`
  - **Type** fn() -> boolean
  - **Description** A method to check if the user is being impersonated.
- **Name** `isRole()`
  - **Type** fn(orgId: string, role: string) -> boolean
  - **Description** A method to check if the user is the provided role in the provided org.
- **Name** `isAtLeastRole()`
  - **Type** fn(orgId: string, role: string) -> boolean
  - **Description** A method to check if the user is at least the provided role in the provided org.
- **Name** `hasPermission()`
  - **Type** fn(orgId: string, permission: string) -> boolean
  - **Description** A method to check if the user has the provided permission in the provided org.
- **Name** `hasAllPermissions()`
  - **Type** fn(orgId: string, permission: string[]) -> boolean
  - **Description** A method to check if the user has all the provided permissions in the provided org.

## [OrgMemberInfo](https://docs.propelauth.com/reference/backend-apis/cloudflare-workers#org-member-info)

The OrgMemberInfo object contains information about the user's membership in an organization.

- **Name** `orgId`
  - **Type** string
  - **Description** The unique id of the organization.
- **Name** `orgName`
  - **Type** string
  - **Description** The name of the organization.
- **Name** `orgMetadata`
  - **Type** object
  - **Description** The metadata associated with the organization.
- **Name** `urlSafeOrgName`
  - **Type** string
  - **Description** The URL-safe name of the organization.
- **Name** `userAssignedRole`
  - **Type** string
  - **Description** The role of the user in the organization.
- **Name** `userInheritedRolesPlusCurrentRole`
  - **Type** string[]
  - **Description** The role of the user within this organization plus each inherited role.
- **Name** `userPermissions`
  - **Type** string[]
  - **Description** A list of permissions the user has in the organization, based on their role.
- **Name** `isRole`
  - **Type** fn(role: string) -> boolean
  - **Description** A function that returns true if the user has the specified role in the organization.
- **Name** `isAtLeastRole`
  - **Type** fn(role: string) -> boolean
  - **Description** A function that returns true if the user has at least the specified role in the organization.
- **Name** `hasPermission`
  - **Type** fn(permission: string) -> boolean
  - **Description** A function that returns true if the user has the specified permission in the organization.
- **Name** `hasAllPermissions`
  - **Type** fn(permissions: string[]) -> boolean
  - **Description** A function that returns true if the user has all of the specified permissions in the organization.
- **Name** `orgRoleStructure`
  - **Type** string
  - **Description** The role structure set for your project. See [multi roles per user](https://docs.propelauth.com/overview/authorization/managing-roles-permissions#multiple-roles-per-user) for more information.
- **Name** `userAssignedAdditionalRoles`
  - **Type** string[]
  - **Description** If using multiple roles per user, returns an array of roles that the user belongs to. Excludes the `userAssignedRole`.
- **Name** `legacyOrgId`
  - **Type** string
  - **Description** If the org was migrated from another system, this will be the ID of the org in the legacy system.

## [Calling Backend APIs](https://docs.propelauth.com/reference/backend-apis/cloudflare-workers#calling-backend-apis)

You can also use the library to call the PropelAuth APIs directly, allowing you to fetch users, create orgs, and a lot more.

```ts
const auth = initAuth({
    authUrl: 'REPLACE_ME',
    apiKey: 'REPLACE_ME',
    verifierKey: 'REPLACE_ME',
})

const magicLink = await auth.createMagicLink({
    email: 'user@customer.com',
})
```

See the [API Reference](https://docs.propelauth.com/reference) for more information.
