Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .github/workflows/prettier.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Prettier Format

on:
pull_request:

jobs:
format:
name: "Format"
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd
with:
ref: ${{ github.head_ref }}
fetch-depth: 0
- name: Install Packages
run: |
corepack enable
pnpm i --frozen-lockfile
- name: Prettier Action
uses: creyD/prettier_action@8c18391fdc98ed0d884c6345f03975edac71b8f0
with:
prettier_options: --write .
git_identity: author
clean_node_folder: false
commit_message: "Automatic code format with Prettier"
2 changes: 1 addition & 1 deletion examples/base-app/.prettierrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"plugins": ["prettier-plugin-tailwindcss"]
}
}
2 changes: 1 addition & 1 deletion examples/kitchen-sink/.prettierrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"plugins": ["prettier-plugin-tailwindcss"]
}
}
62 changes: 44 additions & 18 deletions examples/kitchen-sink/app/auth.ts
Original file line number Diff line number Diff line change
@@ -1,43 +1,59 @@
import cookies from "@twofold/framework/cookies";
import { allow, AuthPolicyProps, AuthPolicyResult, deny, response } from "@twofold/framework/auth";
import {
allow,
AuthPolicyProps,
AuthPolicyResult,
deny,
response,
} from "@twofold/framework/auth";
import { redirect } from "@twofold/framework/redirect";

/**
* This is an example of an authentication policy that layouts, pages, actions and routes can optionally use by exporting a 'const auth: AuthPolicyArray = [allowIfCookieSet]'. Non-default auth policies don't have to be specified in this file, but it's a convention so you know where all your authentication code is.
*
*
* Authentication policies exported from layouts, pages, actions and routes by default inherit the authentication policies from their parent layouts and the root authentication policy.
*
*
* If you want a specific route to discard all of it's authentication policies, you can use the special 'reset' value, like so:
*
*
* import { reset } from "@twofold/framework/auth";
* export const auth: AuthPolicyArray = [reset, otherPolicy];
*
*
* @param props The authentication properties.
* @returns The policy result.
*/
export async function allowIfCookieSet({request}: AuthPolicyProps): Promise<AuthPolicyResult> {
export async function allowIfCookieSet({
request,
}: AuthPolicyProps): Promise<AuthPolicyResult> {
// This is an example of an auth policy that changes it's behaviour based on the request.
if (cookies.get('allow-access') === 'true') {
if (cookies.get("allow-access") === "true") {
return allow();
} else {
return deny("missing cookie");
}
}

export async function behaveBasedOnQueryString({request}: AuthPolicyProps): Promise<AuthPolicyResult> {
export async function behaveBasedOnQueryString({
request,
}: AuthPolicyProps): Promise<AuthPolicyResult> {
// This policy changes it's behaviour based on the query string, and is used for the protected/ content under this app (in addition to the other policies here).
const url = new URL(request.url);
switch (url.searchParams.get("auth-behaviour")) {
case "response":
return response(new Response("Access denied by behaveBasedOnQueryString (response)"));
return response(
new Response("Access denied by behaveBasedOnQueryString (response)"),
);
case "response-throw":
throw new Response("Access denied by behaveBasedOnQueryString (response-throw).");
throw new Response(
"Access denied by behaveBasedOnQueryString (response-throw).",
);
case "deny":
return deny("Access denied by behaveBasedOnQueryString (deny).");
case "deny-throw":
throw "Access denied by behaveBasedOnQueryString (deny-throw).";
case "error":
throw new Error("This is an unhandled error for behaveBasedOnQueryString (error).");
throw new Error(
"This is an unhandled error for behaveBasedOnQueryString (error).",
);
case "redirect":
redirect("/");
case "allow":
Expand All @@ -46,22 +62,30 @@ export async function behaveBasedOnQueryString({request}: AuthPolicyProps): Prom
}
}

export async function behaveBasedOnFormData({request}: AuthPolicyProps): Promise<AuthPolicyResult> {
export async function behaveBasedOnFormData({
request,
}: AuthPolicyProps): Promise<AuthPolicyResult> {
// This policy changes it's behaviour based on the 'behaviour' form data, which is how we demonstrate different behaviour for server actions.
const formData = await request.formData();

// @note: This is '1_behaviour', due to the way React encodes form data fields. Since you're not expected to actually do auth based on form fields, it's fine as a workaround for the example app.
switch (formData.get("1_behaviour")) {
case "response":
return response(new Response("Access denied by behaveBasedOnQueryString (response)"));
return response(
new Response("Access denied by behaveBasedOnQueryString (response)"),
);
case "response-throw":
throw new Response("Access denied by behaveBasedOnQueryString (response-throw).");
throw new Response(
"Access denied by behaveBasedOnQueryString (response-throw).",
);
case "deny":
return deny("Access denied by behaveBasedOnQueryString (deny).");
case "deny-throw":
throw "Access denied by behaveBasedOnQueryString (deny-throw).";
case "error":
throw new Error("This is an unhandled error for behaveBasedOnQueryString (error).");
throw new Error(
"This is an unhandled error for behaveBasedOnQueryString (error).",
);
case "redirect":
redirect("/");
case "allow":
Expand All @@ -72,11 +96,13 @@ export async function behaveBasedOnFormData({request}: AuthPolicyProps): Promise

/**
* The default export from auth.ts is the root authentication policy that applies to all layouts, pages, actions and routes.
*
*
* @param props The authentication properties.
* @returns The policy result.
*/
export default async function defaultPolicy(props: AuthPolicyProps) : Promise<AuthPolicyResult> {
export default async function defaultPolicy(
props: AuthPolicyProps,
): Promise<AuthPolicyResult> {
// This is the default behaviour when auth.ts is not specified.
return allow();

Expand All @@ -98,4 +124,4 @@ export default async function defaultPolicy(props: AuthPolicyProps) : Promise<Au

// returning no value is not permitted per the type system, but
// if you do, it's treated as deny
}
}
Loading