nuxt-auth-utils 0.3.9 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +239 -4
  2. package/dist/module.d.mts +22 -0
  3. package/dist/module.d.ts +22 -0
  4. package/dist/module.json +1 -1
  5. package/dist/module.mjs +40 -2
  6. package/dist/runtime/app/composables/webauthn.d.ts +13 -0
  7. package/dist/runtime/app/composables/webauthn.js +62 -0
  8. package/dist/runtime/server/api/session.get.js +1 -1
  9. package/dist/runtime/server/lib/oauth/auth0.d.ts +1 -1
  10. package/dist/runtime/server/lib/oauth/auth0.js +1 -1
  11. package/dist/runtime/server/lib/oauth/battledotnet.d.ts +1 -1
  12. package/dist/runtime/server/lib/oauth/battledotnet.js +1 -1
  13. package/dist/runtime/server/lib/oauth/cognito.d.ts +1 -1
  14. package/dist/runtime/server/lib/oauth/cognito.js +1 -1
  15. package/dist/runtime/server/lib/oauth/discord.d.ts +1 -1
  16. package/dist/runtime/server/lib/oauth/discord.js +1 -1
  17. package/dist/runtime/server/lib/oauth/dropbox.d.ts +47 -0
  18. package/dist/runtime/server/lib/oauth/dropbox.js +72 -0
  19. package/dist/runtime/server/lib/oauth/facebook.d.ts +1 -1
  20. package/dist/runtime/server/lib/oauth/facebook.js +1 -1
  21. package/dist/runtime/server/lib/oauth/github.d.ts +1 -1
  22. package/dist/runtime/server/lib/oauth/github.js +1 -1
  23. package/dist/runtime/server/lib/oauth/gitlab.d.ts +1 -1
  24. package/dist/runtime/server/lib/oauth/gitlab.js +1 -1
  25. package/dist/runtime/server/lib/oauth/google.d.ts +1 -1
  26. package/dist/runtime/server/lib/oauth/google.js +2 -1
  27. package/dist/runtime/server/lib/oauth/instagram.d.ts +1 -1
  28. package/dist/runtime/server/lib/oauth/instagram.js +1 -1
  29. package/dist/runtime/server/lib/oauth/keycloak.d.ts +1 -1
  30. package/dist/runtime/server/lib/oauth/keycloak.js +1 -1
  31. package/dist/runtime/server/lib/oauth/linkedin.d.ts +1 -1
  32. package/dist/runtime/server/lib/oauth/linkedin.js +1 -1
  33. package/dist/runtime/server/lib/oauth/microsoft.d.ts +1 -1
  34. package/dist/runtime/server/lib/oauth/microsoft.js +1 -1
  35. package/dist/runtime/server/lib/oauth/paypal.d.ts +1 -1
  36. package/dist/runtime/server/lib/oauth/paypal.js +1 -1
  37. package/dist/runtime/server/lib/oauth/spotify.d.ts +1 -1
  38. package/dist/runtime/server/lib/oauth/spotify.js +1 -1
  39. package/dist/runtime/server/lib/oauth/steam.d.ts +1 -1
  40. package/dist/runtime/server/lib/oauth/steam.js +11 -8
  41. package/dist/runtime/server/lib/oauth/tiktok.d.ts +1 -1
  42. package/dist/runtime/server/lib/oauth/tiktok.js +1 -1
  43. package/dist/runtime/server/lib/oauth/twitch.d.ts +1 -1
  44. package/dist/runtime/server/lib/oauth/twitch.js +1 -1
  45. package/dist/runtime/server/lib/oauth/vk.d.ts +1 -1
  46. package/dist/runtime/server/lib/oauth/vk.js +1 -1
  47. package/dist/runtime/server/lib/oauth/x.d.ts +1 -1
  48. package/dist/runtime/server/lib/oauth/x.js +1 -1
  49. package/dist/runtime/server/lib/oauth/xsuaa.d.ts +1 -1
  50. package/dist/runtime/server/lib/oauth/xsuaa.js +1 -1
  51. package/dist/runtime/server/lib/oauth/yandex.d.ts +1 -1
  52. package/dist/runtime/server/lib/oauth/yandex.js +1 -1
  53. package/dist/runtime/server/lib/webauthn/authenticate.d.ts +5 -0
  54. package/dist/runtime/server/lib/webauthn/authenticate.js +73 -0
  55. package/dist/runtime/server/lib/webauthn/register.d.ts +7 -0
  56. package/dist/runtime/server/lib/webauthn/register.js +116 -0
  57. package/dist/runtime/server/lib/webauthn/utils.d.ts +3 -0
  58. package/dist/runtime/server/lib/webauthn/utils.js +35 -0
  59. package/dist/runtime/server/utils/password.d.ts +23 -0
  60. package/dist/runtime/server/utils/password.js +18 -0
  61. package/dist/runtime/types/index.d.ts +1 -0
  62. package/dist/runtime/types/oauth-config.d.ts +1 -1
  63. package/dist/runtime/types/webauthn.d.ts +76 -0
  64. package/dist/runtime/types/webauthn.js +0 -0
  65. package/package.json +23 -9
@@ -0,0 +1,35 @@
1
+ import { useSession, createError } from "h3";
2
+ import { useRuntimeConfig } from "#imports";
3
+ function useChallengeSession(event) {
4
+ return useSession(event, {
5
+ name: "webauthn",
6
+ password: useRuntimeConfig(event).session.password,
7
+ cookie: {
8
+ httpOnly: true,
9
+ secure: true,
10
+ maxAge: 180
11
+ // 3 minutes
12
+ }
13
+ });
14
+ }
15
+ export async function storeChallengeAsSession(event, challenge, challengeId) {
16
+ const challengeSession = await useChallengeSession(event);
17
+ await challengeSession.update({
18
+ data: {
19
+ challenge,
20
+ challengeId
21
+ },
22
+ expires: Date.now() + 180 * 1e3
23
+ // 3 minutes
24
+ });
25
+ }
26
+ export async function getChallengeFromSession(event, challengeId) {
27
+ const challengeSession = await useChallengeSession(event);
28
+ const challenge = challengeSession.data;
29
+ await challengeSession.clear();
30
+ if (challenge.expires < Date.now())
31
+ throw createError({ statusCode: 400, message: "Challenge expired" });
32
+ if (challenge.data.challengeId !== challengeId)
33
+ throw createError({ statusCode: 400, message: "Challenge id mismatch" });
34
+ return challenge.data.challenge;
35
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Hash a password using scrypt
3
+ * @param password - The plain text password to hash
4
+ * @returns The hashed password
5
+ * @example
6
+ * ```ts
7
+ * const hashedPassword = await hashPassword('user_password')
8
+ * ```
9
+ * @more you can configure the scrypt options in `auth.hash.scrypt`
10
+ */
11
+ export declare function hashPassword(password: string): Promise<string>;
12
+ /**
13
+ * Verify a password against a hashed password
14
+ * @param hashedPassword - The hashed password to verify against
15
+ * @param plainPassword - The plain text password to verify
16
+ * @returns `true` if the password is valid, `false` otherwise
17
+ * @example
18
+ * ```ts
19
+ * const isValid = await verifyPassword(hashedPassword, 'user_password')
20
+ * ```
21
+ * @more you can configure the scrypt options in `auth.hash.scrypt`
22
+ */
23
+ export declare function verifyPassword(hashedPassword: string, plainPassword: string): Promise<boolean>;
@@ -0,0 +1,18 @@
1
+ import { Hash } from "@adonisjs/hash";
2
+ import { Scrypt } from "@adonisjs/hash/drivers/scrypt";
3
+ import { useRuntimeConfig } from "#imports";
4
+ let _hash;
5
+ function getHash() {
6
+ if (!_hash) {
7
+ const options = useRuntimeConfig().hash?.scrypt;
8
+ const scrypt = new Scrypt(options);
9
+ _hash = new Hash(scrypt);
10
+ }
11
+ return _hash;
12
+ }
13
+ export async function hashPassword(password) {
14
+ return await getHash().make(password);
15
+ }
16
+ export async function verifyPassword(hashedPassword, plainPassword) {
17
+ return await getHash().verify(hashedPassword, plainPassword);
18
+ }
@@ -1,2 +1,3 @@
1
1
  export type { User, UserSession, UserSessionRequired, UserSessionComposable, SecureSessionData } from './session.js';
2
2
  export type { OAuthConfig, OAuthProvider, OnError } from './oauth-config.js';
3
+ export type { WebAuthnCredential, WebAuthnRegisterEventHandlerOptions, WebAuthnAuthenticateEventHandlerOptions, WebAuthnComposable, WebAuthnUser, } from './webauthn.js';
@@ -1,5 +1,5 @@
1
1
  import type { H3Event, H3Error } from 'h3';
2
- export type OAuthProvider = 'auth0' | 'battledotnet' | 'cognito' | 'discord' | 'facebook' | 'github' | 'gitlab' | 'google' | 'instagram' | 'keycloak' | 'linkedin' | 'microsoft' | 'paypal' | 'spotify' | 'steam' | 'tiktok' | 'twitch' | 'vk' | 'x' | 'xsuaa' | 'yandex' | (string & {});
2
+ export type OAuthProvider = 'auth0' | 'battledotnet' | 'cognito' | 'discord' | 'dropbox' | 'facebook' | 'github' | 'gitlab' | 'google' | 'instagram' | 'keycloak' | 'linkedin' | 'microsoft' | 'paypal' | 'spotify' | 'steam' | 'tiktok' | 'twitch' | 'vk' | 'x' | 'xsuaa' | 'yandex' | (string & {});
3
3
  export type OnError = (event: H3Event, error: H3Error) => Promise<void> | void;
4
4
  export interface OAuthConfig<TConfig, TUser = any, TTokens = any> {
5
5
  config?: TConfig;
@@ -0,0 +1,76 @@
1
+ import type { AuthenticatorTransportFuture } from '@simplewebauthn/types';
2
+ import type { Ref } from 'vue';
3
+ import type { H3Event, H3Error, ValidateFunction } from 'h3';
4
+ import type { GenerateAuthenticationOptionsOpts, GenerateRegistrationOptionsOpts, VerifiedAuthenticationResponse, VerifiedRegistrationResponse } from '@simplewebauthn/server';
5
+ export interface WebAuthnCredential {
6
+ id: string;
7
+ publicKey: string;
8
+ counter: number;
9
+ backedUp: boolean;
10
+ transports?: AuthenticatorTransportFuture[];
11
+ [key: string]: unknown;
12
+ }
13
+ export interface WebAuthnUser {
14
+ userName: string;
15
+ displayName?: string;
16
+ [key: string]: unknown;
17
+ }
18
+ type AllowCredentials = NonNullable<GenerateAuthenticationOptionsOpts['allowCredentials']>;
19
+ type WebAuthnEventHandlerBase<T extends Record<PropertyKey, unknown>> = {
20
+ storeChallenge: (event: H3Event, challenge: string, attemptId: string) => void | Promise<void>;
21
+ getChallenge: (event: H3Event, attemptId: string) => string | Promise<string>;
22
+ onSuccess: (event: H3Event, data: T) => void | Promise<void>;
23
+ onError?: (event: H3Event, error: H3Error) => void | Promise<void>;
24
+ } | {
25
+ storeChallenge?: undefined;
26
+ getChallenge?: undefined;
27
+ onSuccess: (event: H3Event, data: T) => void | Promise<void>;
28
+ onError?: (event: H3Event, error: H3Error) => void | Promise<void>;
29
+ };
30
+ export type WebAuthnRegisterEventHandlerOptions<T extends WebAuthnUser> = WebAuthnEventHandlerBase<{
31
+ user: T;
32
+ credential: WebAuthnCredential;
33
+ registrationInfo: Exclude<VerifiedRegistrationResponse['registrationInfo'], undefined>;
34
+ }> & {
35
+ getOptions?: (event: H3Event) => GenerateRegistrationOptionsOpts | Promise<GenerateRegistrationOptionsOpts>;
36
+ validateUser?: ValidateFunction<T>;
37
+ };
38
+ export type WebAuthnAuthenticateEventHandlerOptions<T extends WebAuthnCredential> = WebAuthnEventHandlerBase<{
39
+ credential: T;
40
+ authenticationInfo: Exclude<VerifiedAuthenticationResponse['authenticationInfo'], undefined>;
41
+ }> & {
42
+ getOptions?: (event: H3Event) => Partial<GenerateAuthenticationOptionsOpts> | Promise<Partial<GenerateAuthenticationOptionsOpts>>;
43
+ getCredential: (event: H3Event, credentialID: string) => T | Promise<T>;
44
+ allowCredentials?: (event: H3Event, userName: string) => AllowCredentials | Promise<AllowCredentials>;
45
+ };
46
+ export interface WebAuthnComposable {
47
+ /**
48
+ * Vue ref (boolean) that checks if the webauthn API is available
49
+ */
50
+ isSupported: Ref<boolean>;
51
+ /**
52
+ * Helper function that checks if the browser supports "Conditional UI" for webauthn
53
+ * @see https://github.com/w3c/webauthn/wiki/Explainer:-WebAuthn-Conditional-UI
54
+ */
55
+ isAutofillSupported: () => Promise<boolean>;
56
+ /**
57
+ * Helper function that returns if platform specific authenticators are available (Touch ID, Face ID, Windows Hello, etc.)
58
+ * You can use this information to prioritize these authenticators over others.
59
+ */
60
+ isPlatformAvailable: () => Promise<boolean>;
61
+ /**
62
+ * Register a credential
63
+ * @param user - The user data to register
64
+ * @param user.userName - The user name to register, can be an email address, a username, or any other form of unique ID chosen by the user
65
+ * @param user.displayName - The display name to register, used for convenience and personalization and should not be relied upon as a secure identifier for authentication processes
66
+ * @returns true if the registration was successful
67
+ */
68
+ register: <T extends WebAuthnUser>(data: T) => Promise<boolean>;
69
+ /**
70
+ * Authenticate a credential
71
+ * @param userName - The user name to authenticate, can be an email address, a username, or any other form of unique ID chosen by the user
72
+ * @returns true if the authentication was successful
73
+ */
74
+ authenticate: (userName?: string) => Promise<boolean>;
75
+ }
76
+ export {};
File without changes
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "nuxt-auth-utils",
3
- "version": "0.3.9",
4
- "description": "Minimalist Auth module for Nuxt with SSR",
5
- "repository": "Atinux/nuxt-auth-utils",
3
+ "version": "0.4.0",
4
+ "description": "Add Authentication to Nuxt applications with secured & sealed cookies sessions.",
5
+ "repository": "atinux/nuxt-auth-utils",
6
6
  "license": "MIT",
7
7
  "type": "module",
8
- "packageManager": "pnpm@9.10.0",
8
+ "packageManager": "pnpm@9.11.0",
9
9
  "exports": {
10
10
  ".": {
11
11
  "types": "./dist/types.d.ts",
@@ -32,26 +32,40 @@
32
32
  "test:watch": "vitest watch"
33
33
  },
34
34
  "dependencies": {
35
+ "@adonisjs/hash": "^9.0.5",
35
36
  "@nuxt/kit": "^3.13.2",
36
37
  "defu": "^6.1.4",
37
38
  "hookable": "^5.5.3",
38
- "ofetch": "^1.3.4",
39
+ "ofetch": "^1.4.0",
39
40
  "ohash": "^1.1.4",
40
41
  "pathe": "^1.1.2",
41
42
  "scule": "^1.3.0",
42
43
  "uncrypto": "^0.1.3"
43
44
  },
45
+ "peerDependencies": {
46
+ "@simplewebauthn/browser": "^10.0.0",
47
+ "@simplewebauthn/server": "^10.0.1"
48
+ },
49
+ "peerDependenciesMeta": {
50
+ "@simplewebauthn/browser": {
51
+ "optional": true
52
+ },
53
+ "@simplewebauthn/server": {
54
+ "optional": true
55
+ }
56
+ },
44
57
  "devDependencies": {
45
- "@iconify-json/simple-icons": "^1.2.3",
58
+ "@iconify-json/simple-icons": "^1.2.4",
46
59
  "@nuxt/devtools": "latest",
47
60
  "@nuxt/eslint-config": "^0.5.7",
48
61
  "@nuxt/module-builder": "^0.8.4",
49
62
  "@nuxt/schema": "^3.13.2",
50
63
  "@nuxt/test-utils": "^3.14.2",
51
- "@nuxt/ui": "^2.18.5",
52
- "@nuxt/ui-pro": "^1.4.2",
64
+ "@nuxt/ui": "^2.18.6",
65
+ "@nuxt/ui-pro": "^1.4.3",
66
+ "@simplewebauthn/types": "^10.0.0",
53
67
  "changelogen": "^0.5.7",
54
- "eslint": "^9.10.0",
68
+ "eslint": "^9.11.1",
55
69
  "nuxt": "^3.13.2",
56
70
  "typescript": "^5.6.2",
57
71
  "vitest": "^2.1.1",