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
3 changes: 3 additions & 0 deletions deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"workspace": ["packages/core", "packages/jose"]
}
1,636 changes: 1,636 additions & 0 deletions deno.lock

Large diffs are not rendered by default.

22 changes: 22 additions & 0 deletions packages/core/deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "@aura-stack/auth",
"version": "0.4.0",
"license": "MIT",
"tasks": {
"dev": "deno run --watch src/index.ts"
},
"exports": {
".": "./src/index.ts",
"./oauth": "./src/oauth/*.ts",
"./types": "./src/@types/index.ts"
},
"imports": {
"@/": "./src/",
"@aura-stack/router": "npm:@aura-stack/router@^0.5.0",
"zod": "npm:zod@^4.3.5"
},
"publish": {
"include": ["src/**/*.ts", "README.md", "CHANGELOG.md"]
},
"exclude": ["dist", "node_modules"]
}
12 changes: 6 additions & 6 deletions packages/core/src/@types/index.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { z } from "zod"
import { createLogEntry } from "@/logger.js"
import { OAuthAccessTokenErrorResponse, OAuthAuthorizationErrorResponse, OAuthEnvSchema } from "@/schemas.js"
import { createJoseInstance, type JWTPayload } from "@/jose.js"
import { createLogEntry } from "@/logger.ts"
import { OAuthAccessTokenErrorResponse, OAuthAuthorizationErrorResponse, OAuthEnvSchema } from "@/schemas.ts"
import { createJoseInstance, type JWTPayload } from "@/jose.ts"
import type { SerializeOptions } from "@aura-stack/router/cookie"
import type { BuiltInOAuthProvider } from "@/oauth/index.js"
import type { LiteralUnion, Prettify } from "@/@types/utility.js"
import type { BuiltInOAuthProvider } from "@/oauth/index.ts"
import type { LiteralUnion, Prettify } from "@/@types/utility.ts"

export * from "./utility.js"
export * from "./utility.ts"

/**
* Standard JWT claims that are managed internally by the token system.
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/actions/callback/access-token.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { fetchAsync } from "@/request.js"
import { AuthInternalError, OAuthProtocolError } from "@/errors.js"
import { OAuthAccessToken, OAuthAccessTokenErrorResponse, OAuthAccessTokenResponse } from "@/schemas.js"
import type { InternalLogger, OAuthProviderCredentials } from "@/@types/index.js"
import { fetchAsync } from "@/request.ts"
import { AuthInternalError, OAuthProtocolError } from "@/errors.ts"
import { OAuthAccessToken, OAuthAccessTokenErrorResponse, OAuthAccessTokenResponse } from "@/schemas.ts"
import type { InternalLogger, OAuthProviderCredentials } from "@/@types/index.ts"

/**
* Make a request to the OAuth provider to the token endpoint to exchange the authorization code provided
Expand Down
22 changes: 11 additions & 11 deletions packages/core/src/actions/callback/callback.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { z } from "zod"
import { createEndpoint, createEndpointConfig, HeadersBuilder } from "@aura-stack/router"
import { createCSRF } from "@/secure.js"
import { cacheControl } from "@/headers.js"
import { isRelativeURL, isSameOrigin, isTrustedOrigin, timingSafeEqual } from "@/assert.js"
import { getUserInfo } from "@/actions/callback/userinfo.js"
import { OAuthAuthorizationErrorResponse } from "@/schemas.js"
import { AuthSecurityError, OAuthProtocolError } from "@/errors.js"
import { getOriginURL, getTrustedOrigins } from "@/actions/signIn/authorization.js"
import { createAccessToken } from "@/actions/callback/access-token.js"
import { createSessionCookie, getCookie, expiredCookieAttributes } from "@/cookie.js"
import type { JWTPayload } from "@/jose.js"
import type { OAuthProviderRecord } from "@/@types/index.js"
import { createCSRF } from "@/secure.ts"
import { cacheControl } from "@/headers.ts"
import { isRelativeURL, isSameOrigin, isTrustedOrigin, timingSafeEqual } from "@/assert.ts"
import { getUserInfo } from "@/actions/callback/userinfo.ts"
import { OAuthAuthorizationErrorResponse } from "@/schemas.ts"
import { AuthSecurityError, OAuthProtocolError } from "@/errors.ts"
import { getOriginURL, getTrustedOrigins } from "@/actions/signIn/authorization.ts"
import { createAccessToken } from "@/actions/callback/access-token.ts"
import { createSessionCookie, getCookie, expiredCookieAttributes } from "@/cookie.ts"
import type { JWTPayload } from "@/jose.ts"
import type { OAuthProviderRecord } from "@/@types/index.ts"

const callbackConfig = (oauth: OAuthProviderRecord) => {
return createEndpointConfig("/callback/:oauth", {
Expand Down
10 changes: 5 additions & 5 deletions packages/core/src/actions/callback/userinfo.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { fetchAsync } from "@/request.js"
import { generateSecure } from "@/secure.js"
import { OAuthErrorResponse } from "@/schemas.js"
import { isNativeError, isOAuthProtocolError, OAuthProtocolError } from "@/errors.js"
import type { InternalLogger, OAuthProviderCredentials, User } from "@/@types/index.js"
import { fetchAsync } from "@/request.ts"
import { generateSecure } from "@/secure.ts"
import { OAuthErrorResponse } from "@/schemas.ts"
import { isNativeError, isOAuthProtocolError, OAuthProtocolError } from "@/errors.ts"
import type { InternalLogger, OAuthProviderCredentials, User } from "@/@types/index.ts"

/**
* Map the default user information fields from the OAuth provider's userinfo response
Expand Down
6 changes: 3 additions & 3 deletions packages/core/src/actions/csrfToken/csrfToken.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createEndpoint } from "@aura-stack/router"
import { createCSRF } from "@/secure.js"
import { secureApiHeaders } from "@/headers.js"
import { setCookie, getCookie } from "@/cookie.js"
import { createCSRF } from "@/secure.ts"
import { secureApiHeaders } from "@/headers.ts"
import { setCookie, getCookie } from "@/cookie.ts"

const getCSRFToken = (request: Request, cookieName: string) => {
try {
Expand Down
10 changes: 5 additions & 5 deletions packages/core/src/actions/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export { signInAction } from "./signIn/signIn.js"
export { callbackAction } from "./callback/callback.js"
export { sessionAction } from "./session/session.js"
export { signOutAction } from "./signOut/signOut.js"
export { csrfTokenAction } from "./csrfToken/csrfToken.js"
export { signInAction } from "./signIn/signIn.ts"
export { callbackAction } from "./callback/callback.ts"
export { sessionAction } from "./session/session.ts"
export { signOutAction } from "./signOut/signOut.ts"
export { csrfTokenAction } from "./csrfToken/csrfToken.ts"
8 changes: 4 additions & 4 deletions packages/core/src/actions/session/session.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { createEndpoint, HeadersBuilder } from "@aura-stack/router"
import { secureApiHeaders } from "@/headers.js"
import { getErrorName, toISOString } from "@/utils.js"
import { expiredCookieAttributes, getCookie } from "@/cookie.js"
import type { JWTStandardClaims, Session, User } from "@/@types/index.js"
import { secureApiHeaders } from "@/headers.ts"
import { getErrorName, toISOString } from "@/utils.ts"
import { expiredCookieAttributes, getCookie } from "@/cookie.ts"
import type { JWTStandardClaims, Session, User } from "@/@types/index.ts"

export const sessionAction = createEndpoint("GET", "/session", async (ctx) => {
const {
Expand Down
10 changes: 5 additions & 5 deletions packages/core/src/actions/signIn/authorization.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { AuthInternalError } from "@/errors.js"
import { OAuthAuthorization } from "@/schemas.js"
import { equals, extractPath, toCastCase } from "@/utils.js"
import { isRelativeURL, isSameOrigin, isValidURL, isTrustedOrigin, patternToRegex } from "@/assert.js"
import { AuthInternalError } from "@/errors.ts"
import { OAuthAuthorization } from "@/schemas.ts"
import { equals, extractPath, toCastCase } from "@/utils.ts"
import { isRelativeURL, isSameOrigin, isValidURL, isTrustedOrigin, patternToRegex } from "@/assert.ts"
import type { GlobalContext } from "@aura-stack/router"
import type { AuthConfig, InternalLogger, OAuthProviderCredentials } from "@/@types/index.js"
import type { AuthConfig, InternalLogger, OAuthProviderCredentials } from "@/@types/index.ts"

/**
* Constructs the request URI for the Authorization Request to the third-party OAuth service. It includes
Expand Down
8 changes: 4 additions & 4 deletions packages/core/src/actions/signIn/signIn.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { z } from "zod"
import { createEndpoint, createEndpointConfig, HeadersBuilder } from "@aura-stack/router"
import { cacheControl } from "@/headers.js"
import { createPKCE, generateSecure } from "@/secure.js"
import { createAuthorizationURL, createRedirectURI, createRedirectTo } from "@/actions/signIn/authorization.js"
import type { OAuthProviderRecord } from "@/@types/index.js"
import { cacheControl } from "@/headers.ts"
import { createPKCE, generateSecure } from "@/secure.ts"
import { createAuthorizationURL, createRedirectURI, createRedirectTo } from "@/actions/signIn/authorization.ts"
import type { OAuthProviderRecord } from "@/@types/index.ts"

const signInConfig = (oauth: OAuthProviderRecord) => {
return createEndpointConfig("/signIn/:oauth", {
Expand Down
12 changes: 6 additions & 6 deletions packages/core/src/actions/signOut/signOut.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { z } from "zod"
import { createEndpoint, createEndpointConfig, HeadersBuilder, statusCode } from "@aura-stack/router"
import { verifyCSRF } from "@/secure.js"
import { secureApiHeaders } from "@/headers.js"
import { AuthSecurityError } from "@/errors.js"
import { getBaseURL, getErrorName } from "@/utils.js"
import { expiredCookieAttributes } from "@/cookie.js"
import { createRedirectTo } from "@/actions/signIn/authorization.js"
import { verifyCSRF } from "@/secure.ts"
import { secureApiHeaders } from "@/headers.ts"
import { AuthSecurityError } from "@/errors.ts"
import { getBaseURL, getErrorName } from "@/utils.ts"
import { expiredCookieAttributes } from "@/cookie.ts"
import { createRedirectTo } from "@/actions/signIn/authorization.ts"

const config = createEndpointConfig({
schemas: {
Expand Down
14 changes: 6 additions & 8 deletions packages/core/src/assert.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { equals } from "@/utils.js"
import { equals } from "@/utils.ts"
import { encoder } from "@aura-stack/jose/crypto"
import type { JWTPayloadWithToken } from "@/@types/index.js"
import type { JWTPayloadWithToken } from "@/@types/index.ts"

export const isFalsy = (value: unknown): boolean => {
return value === false || value === 0 || value === "" || value === null || value === undefined || Number.isNaN(value)
Expand Down Expand Up @@ -126,12 +126,10 @@ export const isTrustedOrigin = (url: string, trustedOrigins: string[]): boolean
export const timingSafeEqual = (a: string, b: string): boolean => {
const bufferA = encoder.encode(a)
const bufferB = encoder.encode(b)
if(bufferA.length !== bufferB.length) {
return false
}
const len = Math.max(bufferA.length, bufferB.length)
let diff = 0
for(let i = 0; i < bufferA.length; i++) {
diff |= bufferA[i] ^ bufferB[i]
for (let i = 0; i < len; i++) {
diff |= (bufferA[i] ?? 0) ^ (bufferB[i] ?? 0)
}
return diff === 0
return diff === 0 && bufferA.length === bufferB.length
}
9 changes: 5 additions & 4 deletions packages/core/src/cookie.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { env } from "@/env.ts"
import { parse, parseSetCookie, serialize, type SerializeOptions } from "@aura-stack/router/cookie"
import { AuthInternalError } from "@/errors.js"
import type { JWTPayload } from "@/jose.js"
import type { AuthRuntimeConfig, CookieStoreConfig, CookieConfig, InternalLogger } from "@/@types/index.js"
import { AuthInternalError } from "@/errors.ts"
import type { JWTPayload } from "@/jose.ts"
import type { AuthRuntimeConfig, CookieStoreConfig, CookieConfig, InternalLogger } from "@/@types/index.ts"

/**
* Prefix for all cookies set by Aura Auth.
Expand Down Expand Up @@ -160,7 +161,7 @@ export const defineSecureCookieOptions = (
attributes.sameSite = "lax"
logger?.log("COOKIE_SAMESITE_NONE_WITHOUT_SECURE")
}
if (process.env.NODE_ENV === "production") {
if (env.NODE_ENV === "production") {
logger?.log("COOKIE_INSECURE_IN_PRODUCTION")
}
if (strategy === "host") {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/errors.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { AuthInternalErrorCode, AuthSecurityErrorCode, ErrorType, LiteralUnion } from "@/@types/index.js"
import type { AuthInternalErrorCode, AuthSecurityErrorCode, ErrorType, LiteralUnion } from "@/@types/index.ts"

/**
* The object returned by the class to users its:
Expand Down
16 changes: 8 additions & 8 deletions packages/core/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { createRouter, type RouterConfig } from "@aura-stack/router"
import { createJoseInstance } from "@/jose.js"
import { createCookieStore } from "@/cookie.js"
import { createErrorHandler, useSecureCookies } from "@/utils.js"
import { createBuiltInOAuthProviders } from "@/oauth/index.js"
import { signInAction, callbackAction, sessionAction, signOutAction, csrfTokenAction } from "@/actions/index.js"
import { createLogEntry, logMessages } from "@/logger.js"
import type { AuthConfig, AuthInstance, InternalLogger, Logger, LogLevel, SyslogOptions } from "@/@types/index.js"
import { createJoseInstance } from "@/jose.ts"
import { createCookieStore } from "@/cookie.ts"
import { createErrorHandler, useSecureCookies } from "@/utils.ts"
import { createBuiltInOAuthProviders } from "@/oauth/index.ts"
import { signInAction, callbackAction, sessionAction, signOutAction, csrfTokenAction } from "@/actions/index.ts"
import { createLogEntry, logMessages } from "@/logger.ts"
import type { AuthConfig, AuthInstance, InternalLogger, Logger, LogLevel, SyslogOptions } from "@/@types/index.ts"

export type {
AuthConfig,
Expand All @@ -21,7 +21,7 @@ export type {
Logger,
LogLevel,
TrustedOrigin,
} from "@/@types/index.js"
} from "@/@types/index.ts"

/**
* Maps LogLevel to Severity hierarchically per RFC 5424.
Expand Down
4 changes: 2 additions & 2 deletions packages/core/src/jose.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { env } from "@/env.js"
import { env } from "@/env.ts"
import {
createJWT,
createJWS,
Expand All @@ -8,7 +8,7 @@ import {
type JWTVerifyOptions,
type DecodedJWTPayloadOptions,
} from "@aura-stack/jose"
import { AuthInternalError } from "@/errors.js"
import { AuthInternalError } from "@/errors.ts"
export { base64url, type JWTPayload } from "@aura-stack/jose/jose"
export { encoder, getRandomBytes, getSubtleCrypto } from "@aura-stack/jose/crypto"

Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/logger.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { SyslogOptions } from "@/@types/index.js"
import type { SyslogOptions } from "@/@types/index.ts"

/**
* Log message definitions organized by category.
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/oauth/bitbucket.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { LiteralUnion, OAuthProviderCredentials } from "@/@types/index.js"
import type { LiteralUnion, OAuthProviderCredentials } from "@/@types/index.ts"

/**
* @see [Get current user](https://developer.atlassian.com/cloud/bitbucket/rest/api-group-users/#api-user-get)
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/oauth/discord.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { OAuthProviderCredentials } from "@/@types/index.js"
import type { OAuthProviderCredentials } from "@/@types/index.ts"

/**
* @see [Discord - Nameplate Object](https://discord.com/developers/docs/resources/user#nameplate-nameplate-structure)
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/oauth/figma.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { OAuthProviderCredentials } from "@/@types/index.js"
import type { OAuthProviderCredentials } from "@/@types/index.ts"
Comment thread
halvaradop marked this conversation as resolved.

/**
* @see [Figma API - Users](https://developers.figma.com/docs/rest-api/users-types/)
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/oauth/github.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { OAuthProviderCredentials } from "@/@types/index.js"
import type { OAuthProviderCredentials } from "@/@types/index.ts"

/**
* @see [Get the authenticated user](https://docs.github.com/en/rest/users/users?apiVersion=2022-11-28#get-the-authenticated-user)
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/oauth/gitlab.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { OAuthProviderCredentials } from "@/@types/index.js"
import type { OAuthProviderCredentials } from "@/@types/index.ts"

/**
* @see [GitLab - User Structure](https://docs.gitlab.com/ee/api/users.html#external-user-structure)
Expand Down
50 changes: 25 additions & 25 deletions packages/core/src/oauth/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,32 @@
*
* This modules re-exports OAuth providers available in Aura Auth to be used in the Auth instance configuration.
*/
import type { LiteralUnion, OAuthProviderCredentials } from "@/@types/index.js"
import { env } from "@/env.js"
import { github } from "./github.js"
import { bitbucket } from "./bitbucket.js"
import { figma } from "./figma.js"
import { discord } from "./discord.js"
import { gitlab } from "./gitlab.js"
import { spotify } from "./spotify.js"
import { x } from "./x.js"
import { strava } from "./strava.js"
import { mailchimp } from "./mailchimp.js"
import { pinterest } from "./pinterest.js"
import { OAuthEnvSchema, OAuthProviderCredentialsSchema } from "@/schemas.js"
import { AuthInternalError } from "@/errors.js"
import { formatZodError } from "@/utils.js"
import type { LiteralUnion, OAuthProviderCredentials } from "@/@types/index.ts"
import { env } from "@/env.ts"
import { github } from "./github.ts"
import { bitbucket } from "./bitbucket.ts"
import { figma } from "./figma.ts"
import { discord } from "./discord.ts"
import { gitlab } from "./gitlab.ts"
import { spotify } from "./spotify.ts"
import { x } from "./x.ts"
import { strava } from "./strava.ts"
import { mailchimp } from "./mailchimp.ts"
import { pinterest } from "./pinterest.ts"
import { OAuthEnvSchema, OAuthProviderCredentialsSchema } from "@/schemas.ts"
import { AuthInternalError } from "@/errors.ts"
import { formatZodError } from "@/utils.ts"

export * from "./github.js"
export * from "./bitbucket.js"
export * from "./figma.js"
export * from "./discord.js"
export * from "./gitlab.js"
export * from "./spotify.js"
export * from "./x.js"
export * from "./strava.js"
export * from "./mailchimp.js"
export * from "./pinterest.js"
export * from "./github.ts"
export * from "./bitbucket.ts"
export * from "./figma.ts"
export * from "./discord.ts"
export * from "./gitlab.ts"
export * from "./spotify.ts"
export * from "./x.ts"
export * from "./strava.ts"
export * from "./mailchimp.ts"
export * from "./pinterest.ts"

export const builtInOAuthProviders = {
github,
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/oauth/mailchimp.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { OAuthProviderCredentials } from "@/@types/index.js"
import type { OAuthProviderCredentials } from "@/@types/index.ts"

export interface Login {
email: string
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/oauth/pinterest.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { LiteralUnion, OAuthProviderCredentials } from "@/@types/index.js"
import type { LiteralUnion, OAuthProviderCredentials } from "@/@types/index.ts"

/**
* @see [Pinterest - Get User Account](https://developers.pinterest.com/docs/api/v5/user_account-get)
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/oauth/spotify.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { OAuthProviderCredentials } from "@/@types/index.js"
import type { OAuthProviderCredentials } from "@/@types/index.ts"

export interface SpotifyImage {
url: string
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/oauth/strava.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { OAuthProviderCredentials } from "@/@types/index.js"
import type { OAuthProviderCredentials } from "@/@types/index.ts"

/**
* @see [Strava - SummaryClub](https://developers.strava.com/docs/reference/#api-models-SummaryClub)
Expand Down
Loading
Loading