Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3.1.7 #107

Merged
merged 3 commits into from
Jun 24, 2024
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
18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nuxt-alt/auth",
"version": "3.1.4",
"version": "3.1.7",
"description": "An alternative module to @nuxtjs/auth",
"homepage": "https://github.com/nuxt-alt/auth",
"author": "Denoder",
Expand Down Expand Up @@ -37,24 +37,24 @@
},
"dependencies": {
"@nuxt-alt/http": "latest",
"@nuxt/kit": "^3.9.1",
"@nuxt/kit": "^3.12.2",
"@refactorjs/serialize": "latest",
"cookie-es": "^1.0.0",
"cookie-es": "^1.1.0",
"defu": "^6.1.3",
"jwt-decode": "^4.0.0",
"ohash": "^1.1.3",
"pathe": "^1.1.1",
"pathe": "^1.1.2",
"pinia": "^2.1.7",
"requrl": "^3.0.2"
},
"devDependencies": {
"@nuxt-alt/proxy": "^2.4.8",
"@nuxt/schema": "^3.9.1",
"@nuxt-alt/proxy": "^2.5.8",
"@nuxt/schema": "^3.12.2",
"@nuxtjs/i18n": "next",
"@types/node": "^20",
"jiti": "^1.21.0",
"nuxt": "^3.9.1",
"typescript": "^5.3.3",
"jiti": "^1.21.6",
"nuxt": "^3.9.3",
"typescript": "5.3.3",
"unbuild": "^2.0.0"
},
"repository": {
Expand Down
4 changes: 2 additions & 2 deletions src/plugin.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { ModuleOptions, Strategy, ImportOptions } from './types';
import type { ModuleOptions, StrategyOptions, ImportOptions } from './types';
import { serialize } from '@refactorjs/serialize';

export const getAuthPlugin = (options: {
options: ModuleOptions
schemeImports: ImportOptions[]
strategies: Strategy[]
strategies: StrategyOptions[]
strategyScheme: Record<string, ImportOptions>
}): string => {
return `import { Auth, ExpiredAuthSessionError } from '#auth/runtime'
Expand Down
43 changes: 24 additions & 19 deletions src/resolve.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
import type { Strategy, ModuleOptions, ProviderNames, SchemeNames, ImportOptions } from './types';
import type { StrategyOptions, ModuleOptions, SchemeNames, ImportOptions } from './types';
import type { Nuxt } from '@nuxt/schema';
import { OAUTH2DEFAULTS, LOCALDEFAULTS, ProviderAliases, BuiltinSchemes } from './runtime/inc/default-properties';
import { addAuthorize, addLocalAuthorize, assignAbsoluteEndpoints, assignDefaults } from './utils/provider';
import { OAUTH2DEFAULTS, LOCALDEFAULTS, ProviderAliases, BuiltinSchemes, LocalSchemes, OAuth2Schemes } from './runtime/inc/default-properties';
import { addAuthorize, addLocalAuthorize, assignAbsoluteEndpoints, assignDefaults, } from './utils/provider';
import { hasOwn } from './utils';
import * as AUTH_PROVIDERS from './runtime/providers';
import { resolvePath } from '@nuxt/kit';
import { existsSync } from 'fs';
import { hash } from 'ohash';

export async function resolveStrategies(nuxt: Nuxt, options: ModuleOptions) {
const strategies: Strategy[] = [];
const strategies: StrategyOptions[] = [];
const strategyScheme = {} as Record<string, ImportOptions>;

for (const name of Object.keys(options.strategies!)) {
if (!options.strategies![name] || (options.strategies as Strategy)[name].enabled === false) {
if (!options.strategies?.[name] || options.strategies?.[name].enabled === false) {
continue;
}

// Clone strategy
const strategy = Object.assign({}, options.strategies![name]) as Strategy;
const strategy = Object.assign({}, options.strategies![name]);

// Default name
if (!strategy.name) {
Expand All @@ -26,14 +27,18 @@ export async function resolveStrategies(nuxt: Nuxt, options: ModuleOptions) {

// Default provider (same as name)
if (!strategy.provider) {
strategy.provider = strategy.name as ProviderNames;
strategy.provider = strategy.name;
}

// Determine if SSR is enabled
strategy.ssr = nuxt.options.ssr
if (hasOwn(strategy, 'ssr')) {
strategy.ssr = strategy.ssr;
} else {
strategy.ssr = nuxt.options.ssr;
}

// Try to resolve provider
const provider = await resolveProvider(strategy.provider, nuxt, strategy);
const provider = await resolveProvider(strategy.provider as string, nuxt, strategy);

delete strategy.provider;

Expand All @@ -50,7 +55,7 @@ export async function resolveStrategies(nuxt: Nuxt, options: ModuleOptions) {
// Resolve and keep scheme needed for strategy
const schemeImport = await resolveScheme(strategy.scheme);
delete strategy.scheme;
strategyScheme[strategy.name] = schemeImport as ImportOptions;
strategyScheme[strategy.name] = schemeImport!;

// Add strategy to array
strategies.push(strategy);
Expand Down Expand Up @@ -90,7 +95,7 @@ export async function resolveScheme(scheme: string) {
}
}

export async function resolveProvider(provider: string | ((...args: any[]) => any), nuxt: Nuxt, strategy: Strategy) {
export async function resolveProvider(provider: string | ((nuxt: Nuxt, strategy: StrategyOptions, ...args: any[]) => void), nuxt: Nuxt, strategy: StrategyOptions) {
provider = (ProviderAliases[provider as keyof typeof ProviderAliases] || provider);

if (AUTH_PROVIDERS[provider as keyof typeof AUTH_PROVIDERS]) {
Expand All @@ -104,20 +109,20 @@ export async function resolveProvider(provider: string | ((...args: any[]) => an

// return an empty function as it doesn't use a provider
if (typeof provider === 'string') {
return (nuxt: Nuxt, strategy: Strategy) => {
if (['oauth2', 'openIDConnect', 'auth0'].includes(strategy.scheme!) && strategy.ssr) {
assignDefaults(strategy as any, OAUTH2DEFAULTS)
addAuthorize(nuxt, strategy as any, true)
return (nuxt: Nuxt, strategy: StrategyOptions) => {
if (OAuth2Schemes.includes(strategy.scheme!) && strategy.ssr) {
assignDefaults(strategy, OAUTH2DEFAULTS as typeof strategy)
addAuthorize(nuxt, strategy, true)
}

if (['refresh', 'local', 'cookie'].includes(strategy.scheme!) && strategy.ssr) {
assignDefaults(strategy as any, LOCALDEFAULTS)
if (LocalSchemes.includes(strategy.scheme!) && strategy.ssr) {
assignDefaults(strategy, LOCALDEFAULTS as typeof strategy)

if (strategy.url) {
assignAbsoluteEndpoints(strategy as any);
assignAbsoluteEndpoints(strategy);
}

addLocalAuthorize(nuxt, strategy as any)
addLocalAuthorize(nuxt, strategy)
}
}
}
Expand Down
29 changes: 18 additions & 11 deletions src/runtime/core/storage.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
import type { ModuleOptions, AuthStore, AuthState, StoreMethod, StoreIncludeOptions } from '../../types';
import type { NuxtApp } from '#app';
import type { Pinia, StoreDefinition } from 'pinia';
import { type Pinia, type StoreDefinition, defineStore } from 'pinia';
import { isUnset, isSet, decodeValue, encodeValue, setH3Cookie } from '../../utils';
import { parse, serialize, type CookieSerializeOptions } from 'cookie-es';
import { useState } from '#imports';
import { watch, type Ref } from 'vue';
import { useState } from '#imports';

/**
* @class Storage
* @classdesc Storage class for stores and cookies
* @param { NuxtApp } ctx - Nuxt app context
* @param { ModuleOptions } options - Module options
*/
export class Storage {
ctx: NuxtApp;
options: ModuleOptions;
#PiniaStore!: StoreDefinition;
#initPiniaStore!: AuthStore;
#initStore!: Ref<AuthState>;
state: AuthState;
memory!: Ref<AuthState>;
#internal!: Ref<AuthState>;
memory!: AuthState;
#piniaEnabled: boolean = false;

constructor(ctx: NuxtApp, options: ModuleOptions) {
Expand Down Expand Up @@ -106,22 +113,22 @@ export class Storage {
this.#piniaEnabled = this.options.stores.pinia!?.enabled! && !!pinia;

if (this.#piniaEnabled) {
const { defineStore } = await import('pinia')
this.#PiniaStore = defineStore(this.options.stores.pinia?.namespace!, {
this.#PiniaStore = defineStore(this.options.stores.pinia?.namespace as string, {
state: (): AuthState => ({ ...this.options.initialState })
});

this.#initPiniaStore = this.#PiniaStore(pinia)
this.state = this.#initPiniaStore;
} else {
this.#initStore = useState<AuthState>(this.options.stores.state?.namespace, () => ({
this.#initStore = useState<AuthState>(this.options.stores.state?.namespace as string, () => ({
...this.options.initialState
}))

this.state = this.#initStore.value
}

this.memory = useState<AuthState>('auth-internal', () => ({}))
this.#internal = useState<AuthState>('auth-internal', () => ({}))
this.memory = this.#internal.value
}

get pinia() {
Expand All @@ -134,7 +141,7 @@ export class Storage {

setState(key: string, value: any) {
if (key.startsWith('_')) {
this.memory.value[key] = value;
this.memory[key] = value;
}
else if (this.#piniaEnabled) {
this.#initPiniaStore.$patch({ [key]: value });
Expand All @@ -150,7 +157,7 @@ export class Storage {
if (!key.startsWith('_')) {
return this.state[key];
} else {
return this.memory.value[key];
return this.memory[key];
}
}

Expand Down Expand Up @@ -214,7 +221,7 @@ export class Storage {
isLocalStorageEnabled(): boolean {
const isNotServer = !process.server;
const isConfigEnabled = this.options.stores.local?.enabled;
const localTest = "test";
const localTest = 'test';

if (isNotServer && isConfigEnabled) {
try {
Expand Down Expand Up @@ -278,7 +285,7 @@ export class Storage {
const isNotServer = !process.server;
// @ts-ignore
const isConfigEnabled = this.options.stores!.session?.enabled;
const testKey = "test";
const testKey = 'test';

if (isNotServer && isConfigEnabled) {
try {
Expand Down
19 changes: 16 additions & 3 deletions src/runtime/inc/default-properties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,22 @@ export const ProviderAliases = {
export const BuiltinSchemes = {
local: 'LocalScheme',
cookie: 'CookieScheme',
oauth2: 'Oauth2Scheme',
openIDConnect: 'OpenIDConnectScheme',
refresh: 'RefreshScheme',
laravelJWT: 'LaravelJWTScheme',
oauth2: 'Oauth2Scheme',
openIDConnect: 'OpenIDConnectScheme',
auth0: 'Auth0Scheme',
};
};

export const LocalSchemes = [
'local',
'cookie',
'refresh',
'laravelJWT',
]

export const OAuth2Schemes = [
'oauth',
'openIDConnect',
'auth0',
]
3 changes: 1 addition & 2 deletions src/runtime/inc/id-token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,13 @@ export class IdToken {
}

reset() {
this.scheme.requestHandler!.clearHeader();
this.#resetSSRToken();
this.#setToken(undefined);
this.#setExpiration(undefined);
}

status(): TokenStatus {
return new TokenStatus(this.get(), this.#getExpiration());
return new TokenStatus(this.get(), this.#getExpiration(), this.scheme.options.idToken?.httpOnly);
}

#resetSSRToken(): void {
Expand Down
4 changes: 2 additions & 2 deletions src/runtime/inc/refresh-token.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,13 @@ export class RefreshToken {
}

reset(): void {
this.#resetSSRToken()
this.#resetSSRToken();
this.#setToken(undefined);
this.#setExpiration(undefined);
}

status(): TokenStatus {
return new TokenStatus(this.get(), this.#getExpiration(), this.scheme.options.refreshToken.httpOnly);
return new TokenStatus(this.get(), this.#getExpiration(), this.scheme.options.refreshToken?.httpOnly);
}

#resetSSRToken(): void {
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/inc/request-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export class RequestHandler {
this.auth = auth;
this.requestInterceptor = null;
this.responseErrorInterceptor = null;
this.currentToken = this.auth.$storage.memory.value?.[this.scheme.options.token!.prefix + this.scheme.options.name] as string
this.currentToken = this.auth.$storage?.memory?.[this.scheme.options.token!?.prefix + this.scheme.options.name] as string
}

setHeader(token: string): void {
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/schemes/auth0.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { withQuery } from 'ufo';
import { Oauth2Scheme } from '../schemes/oauth2';

export class Auth0Scheme extends Oauth2Scheme {
logout(): void {
override logout(): void {
this.$auth.reset();

const opts = {
Expand Down
10 changes: 5 additions & 5 deletions src/runtime/schemes/cookie.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export class CookieScheme<OptionsT extends CookieSchemeOptions> extends LocalSch
super($auth, options as OptionsT, DEFAULTS as OptionsT);
}

async mounted(): Promise<HTTPResponse<any> | void> {
override async mounted(): Promise<HTTPResponse<any> | void> {
if (process.server) {
this.$auth.ctx.$http.setHeader('referer', this.$auth.ctx.ssrContext!.event.node.req.headers.host!);
}
Expand All @@ -59,7 +59,7 @@ export class CookieScheme<OptionsT extends CookieSchemeOptions> extends LocalSch
return this.$auth.fetchUserOnce();
}

check(): SchemeCheck {
override check(): SchemeCheck {
const response = { valid: false };

if (!super.check().valid && this.options.token?.type) {
Expand All @@ -82,7 +82,7 @@ export class CookieScheme<OptionsT extends CookieSchemeOptions> extends LocalSch
return response;
}

async login(endpoint: HTTPRequest): Promise<HTTPResponse<any> | void> {
override async login(endpoint: HTTPRequest): Promise<HTTPResponse<any> | void> {
// Ditch any leftover local tokens before attempting to log in
this.$auth.reset();

Expand Down Expand Up @@ -119,7 +119,7 @@ export class CookieScheme<OptionsT extends CookieSchemeOptions> extends LocalSch
return response;
}

async fetchUser(endpoint?: HTTPRequest): Promise<HTTPResponse<any> | void> {
override async fetchUser(endpoint?: HTTPRequest): Promise<HTTPResponse<any> | void> {
if (!this.check().valid) {
return Promise.resolve();
}
Expand Down Expand Up @@ -156,7 +156,7 @@ export class CookieScheme<OptionsT extends CookieSchemeOptions> extends LocalSch
});
}

reset(): void {
override reset(): void {
if (this.options.cookie.name) {
this.$auth.$storage.setCookie(this.options.cookie.name, null);
}
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/schemes/laravel-jwt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { HTTPResponse } from '../../types';
import { RefreshScheme } from './refresh';

export class LaravelJWTScheme extends RefreshScheme {
protected updateTokens(response: HTTPResponse<any>): void {
protected override updateTokens(response: HTTPResponse<any>): void {
super.updateTokens(response);
}
}
1 change: 1 addition & 0 deletions src/runtime/schemes/local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ export class LocalScheme<OptionsT extends LocalSchemeOptions = LocalSchemeOption
this.$auth.reset({ resetInterceptor: false });
}

endpoint = endpoint || {};
endpoint.body = endpoint.body || {};

// Add client id to payload if defined
Expand Down
Loading
Loading