Giter VIP home page Giter VIP logo

oslo's People

Contributors

aarono avatar aayushbtw avatar elliottstorey avatar fcannizzaro avatar flunsi avatar gavriguy avatar kazuumin avatar khazixi avatar linusop avatar marcomuser avatar pawelblaszczyk5 avatar pilcrowonpaper avatar rmarscher avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

oslo's Issues

Adding function to convert uri into image

In this link we have const qrcode = createQRCode(uri); as placeholders. I had reviewed a few libraries to add an implemention to my project. I think this one is the most stable https://kazuhikoarase.github.io/qrcode-generator/js/demo/ and pure js. Using it is pretty straight forward I was wondering if I can add it as a function under oslo/otp

import { qrcode } from "$lib/qrcode"
var typeNumber = 0;
var errorCorrectionLevel = 'M';
var qr = qrcode(typeNumber, errorCorrectionLevel);
qr.addData(uri);
qr.make();
console.log(qr.createImgTag())

Support Bearer authentication for OAuth token requests

If you enable certificate authentication instead of token authentication in Microsoft Entra ID, you must authenticate via a Bearer token. (see https://learn.microsoft.com/en-us/answers/questions/346048/how-to-get-access-token-from-client-certificate-ca)
This is currently not supported by oslo.

I have already begun implementing this option and it seems like a trivial change (main...m-radmacher:oslo:feat/oauth-jwt-authentication).

If you're interested in merging this I would probably need to update the docs further.

[FEATURE] Export the TimeSpanUnit type

Export the TimeSpanUnit type to make it reusable

image

I wanted to make the sessionExpiresIn attribute in Lucia customizable. For now, I temporarily created an assertion.

image

Support OpenId 2.0

I was trying out lucia, arctic and oslo on a recent project and had a great experience using these libraries!

Wanting to replace the auth system in another project which currently uses Passport (because it supports authentication via Steam) made me realize, that oslo does not support OpenId, let alone old OpenId 2.0 Steam is using to this day.

I'd really appreciate support for OpenId / Steam auth. One reason being that almost all libraries implementing Steam authentication use an old openid package that hasn't been updated in years (except for some dependency updates). Another reason is that those packages, namely passport and passport-steam, are a bit outdated I feel and are not native TypeScript projects.

I'd be willing to try to put together a PR, but I've never really tinkered with auth at its core. Though, I have looked at packages implementing Steam auth and have a slight idea of how it works. However, replacing openid with something custom has me on edge because I haven't really understood how it works or why you'd need it - and I'd rather not code any vulnerabilities into a package.

JWT `aud` Claim Does Not Match JWT Spec

Upon reviewing the oslo module, I've found its features compelling and plan on integrating it into our production applications. However, I've noticed an inconsistency concerning the oslo/jwt not completely adhering to the JWT spec.

According to Section 4.1.3 of the spec, the aud claim should usually be an array of strings, although it can also be just a string.

Section 4.1.3 JWT Spec

Looking your library's source code, I noticed that it only supports string as the type of audience. Can you confirm if this was an intentional design decision?

If not, I am happy to contribute by making a PR to resolve this issue.

Module parse failed: Unexpected character '�' (1:0)

I have a Next.js 14 project set up with the pages router. But, as I am setting up Lucia (I'm following the Username and Password Tutorial to set it up. But, I keep getting the following error message.

./node_modules/.pnpm/@[email protected]/node_modules/@node-rs/argon2-darwin-x64/argon2.darwin-x64.node
Module parse failed: Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)

I'm using PNPM as the package manager but I don't think that should cause any problems.

Error importing `oslo` in NestJS

Having trouble using this package in a NestJS app, I guess because NestJS is still stuck on CommonJS unfortunately. Instead of importing like other packages, I do this inline in code:

const { Argon2id } = await import('oslo/password');
const argon2id = new Argon2id();
const hash = await argon2id.hash(password);

However, I get the below error:

Error [ERR_REQUIRE_ESM]: require() of ES Module /node_modules/oslo/dist/password/index.js from /dist/api/auth/auth.service.js not supported.

Instead change the require of index.js in /dist/api/auth/auth.service.js to a dynamic import() which is available in all CommonJS modules.

That's what I'm doing above and tried many different variations. Anything else I can try or missing?

validateJWT example in docs does not match definition

The example shown on https://oslo.js.org/reference/jwt/validateJWT is:

import { validateJWT } from "oslo/jwt";

try {
	const jwt = validateJWT(
		"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXNzYWdlIjoiaGVsbG8ifQ.yP03DaEblJkk9mR-Y5L7YCMzJgHL-RDPx90aXz-cuAI"
	);
	const message = jwt.payload.message;
} catch {
	// invalid signature
	// expired token
	// inactive token (`nbf`)
}

where a single string argument is passed to the validateJWT function.

However, the Definition in the docs is:

function validateJWT(
	algorithm: JWTAlgorithm,
	key: ArrayBuffer | TypedArray,
	jwt: string
): Promise<JWT>;

which matches the code.

Support for JWKS?

I'm interested in support for JWKS. To me that means:

  1. Create a public/private key set
  2. Sign JWKs with private key
  3. Verify JWKs with a public key

In the past I have typically used https://mkjwk.org but I would much prefer a holistic solution from this great library. Thanks!

Why is auri listed as a dependency

Auri is listed as dev dependency in lucia, but is a main dependency in both oslo and arctic. It is unused in prod code, and also installs 11 additional unused packages.

OAuth2 pass credentials in url

I'm trying to validate the authorization code with the client_secret in the url

Looking at the code, it doesn't seem to be allowed, can you help me?

this is the expected url to validate the code
/v1/grant/?grant_type=authorization_code&client_id=[your_developer_id]&redirect_uri=[your_callback_url]&client_secret=[your_client_secret_code]&code=[your_authorization_code]


authenticateWith only has 2 options: request_body or http_basic_auth (default)
probably it needs to have a third option to allow it in search params ?

Incorrect maxAge in cookie

I've been having this issue for the passed few days now where i am logged out when i open my application the next morning.

I found out the the Expires / Max-Age in the cookie is wrong even when i make sessionCookie expires: false in lucia,

it is currently setting the Expires / Max-Age as seconds, when converted to milliseconds i works as expected

maxAge: this.cookieExpiresIn?.seconds()

Vercel adapter not working with node-rs/bcrypt

Currently I have an issue using the latest version of vercel adapter in my sveltekit app.

The message appears on prod build:
Warning: The following modules failed to locate dependencies that may (or may not) be required for your app to work: ...

I tested the node adapter and it seems to work fine with that.
Is there a way to fix it for vercel apps? I think vercel does not have all the node dependencies on their edge runtime: vercel blog

They suggest to use a different library such as bcrypt.js

Signed cookie support?

Could working with signed cookies be made easier? For example maybe including a secrets parameter when creating and verifying cookies?

Support for additional headers in OAuth token request

Hi,

while testing the library with entra id, I got the following error while trying to get the tokens:

AADSTS9002327: Tokens issued for the 'Single-Page Application' client-type may only be redeemed via cross-origin requests. Trace ID: <traceId> Correlation ID: <correlationId> Timestamp: 2024-03-22 09:42:30Z

Would it make sense the add a additional option to the validateAuthorizationCode method to set the required headers?

My current workaround is to create my own token request.


Not sure if this is a problem with all providers, but based on what I have seen, it seems that EntraID needs the origin header in the token request if we use a "public client".

Not sure if it helps, but here the code which I have used to test it.
( used hono via npm create hono@latest and updated the src/index.ts with the code below )

// required environment variables are:
// TENANT_ID and APP_ID

import { serve } from "@hono/node-server";
import { Hono } from "hono";
import { deleteCookie, getCookie, setCookie } from "hono/cookie";
import { MicrosoftEntraId, generateState, generateCodeVerifier } from "arctic";

import got from "got";
import { inspect } from "util";

const app = new Hono();

const redirectUri = "http://localhost:3000/api/auth/callback";

const entraId = new MicrosoftEntraId(
  process.env.TENANT_ID,
  process.env.APP_ID,
  "",
  redirectUri
);

app.get("/", async (c) => {
  const state = generateState();
  const codeVerifier = generateCodeVerifier();

  const url = await entraId.createAuthorizationURL(state, codeVerifier, {
    scopes: ["openid", "profile", "email", `${process.env.APP_ID}/.default`],
  });

  // store state verifier as cookie
  setCookie(c, "state", state, {
    secure: false,
    path: "/",
    httpOnly: true,
    maxAge: 60 * 10, // 10 min
  });

  // store code verifier as cookie
  setCookie(c, "code_verifier", codeVerifier, {
    secure: false,
    path: "/",
    httpOnly: true,
    maxAge: 60 * 10, // 10 min
  });
  return c.html(`
    <div>
      <a href="${url}">Get access token</a>
    </div>
  `);
});

app.get("/api/auth/callback", async (c) => {
  const code = c.req.query("code");
  const state = c.req.query("state");

  const storedState = getCookie(c, "state");
  const storedCodeVerifier = getCookie(c, "code_verifier");

  if (!code || !storedState || !storedCodeVerifier || state !== storedState) {
    // 400
    throw new Error("Invalid request");
  }

  /**
   * since we can't (yet) set the origin for the token request
   * we have to use our own implementation to get the tokens
   * implementation is based on https://github.com/pilcrowOnPaper/oslo/blob/main/src/oauth2/index.ts
   */
  // const tokens = await entraId.validateAuthorizationCode(
  //   code,
  //   storedCodeVerifier
  // );

  const tokenResponse = await got(
    `https://login.microsoftonline.com/${env.TENANT_ID}/oauth2/v2.0/token`,
    {
      method: "post",
      form: {
        code: code,
        client_id: process.env.APP_ID,
        grant_type: "authorization_code",
        redirect_uri: redirectUri,
        code_verifier: storedCodeVerifier,
      },
      responseType: "json",
      headers: {
        origin: redirectUri,
      },
      throwHttpErrors: false,
    }
  );

  deleteCookie(c, "code");
  deleteCookie(c, "state");

  if (!tokenResponse.ok) {
    console.log({ error: tokenResponse.body });
    return c.text(
      "Something went wrong while fetching the tokens ( check the console for more details )"
    );
  }

  return c.text(inspect(tokenResponse.body, { depth: 2 }));
});

const port = 3000;
console.log(`Server is running on port ${port}`);

serve({
  fetch: app.fetch,
  port,
});

[oslo/crypto] Accept `TypedArray` in addition to `ArrayBuffer`

Currently, the createJWT method only accepts the key as an ArrayBuffer. This is probably because many methods in oslo/crypto only accept an ArrayBuffer. However, the Web Crypto API often accepts TypedArray (eg. Uint8Array) and DataView as well.

My personal use-case is that I am using JWTs in cookie sessions. Instead of generating the JWT key at runtime, I want to save the JWT key as a string, so the sessions are valid even when I restart the server.

In any case, ArrayBuffer is harder to create/manipulate than Uint8Array.

Because the Web Crypto API is compatible either way, this shouldn't require any changes in logic (just type-defs).


PS: Thanks so much for your work here and with lucia. It means I have one less thing to worry about when implementing authentication.

Dependency minimization

@node-rs/argon2 and @node-rs/bcrypt are only required by the password provider and pull many huge dependencies (with binaries).
Is it possible to make it optional and reduce the number of dependencies ?

Unexpected character '�'

I get the following error in a SolidStart project (i.e. using Vite) after upgrading to [email protected]:

[commonjs--resolver] Unexpected character '�' (Note that you need plugins to import files that are not JavaScript)
file: /Users/erikmuller/cn-webapp/node_modules/@node-rs/argon2/index.js:1:0
1: ����
       ���__TEXT@__text...
   ^
2: �H__LINKEDIT�
�/Users/runner/work/node-rs/node-rs/target/aarch6...

[12:36:09 AM]  ERROR  Unexpected character '�' (Note that you need plugins to import files that are not JavaScript)

  at error (node_modules/vinxi/node_modules/vite/node_modules/rollup/dist/es/shared/node-entry.js:2287:30)
  at Module.error (node_modules/vinxi/node_modules/vite/node_modules/rollup/dist/es/shared/node-entry.js:13745:16)
  at Module.tryParse (node_modules/vinxi/node_modules/vite/node_modules/rollup/dist/es/shared/node-entry.js:14476:25)
  at Module.setSource (node_modules/vinxi/node_modules/vite/node_modules/rollup/dist/es/shared/node-entry.js:14077:39)
  at ModuleLoader.addModuleSource (node_modules/vinxi/node_modules/vite/node_modules/rollup/dist/es/shared/node-entry.js:24649:20)

The issue has also been reported for SvelteKit project here and the resolution proposed in this post doesn't work for me.

SameSite cookie attribute compatibilty with Hono

I'm currently working on integrating Lucia and Oslo with a Hono API and noticed the typing for the SameSite in the Cookie is not compatible with one used by Hono, when looking at the documentation on MDN website it seems that Hono are using the same one as MDN documentation.

Example

This gives a type error :

const session = await lucia.createSession(createdUser.userId, {});
const sessionCookie = lucia.createSessionCookie(session.id);

setCookie(ctx, sessionCookie.name, sessionCookie.value, {
  ...sessionCookie.attributes,
});
Argument of type '{ secure?: boolean; path?: string; domain?: string; sameSite?: "lax" | "strict" | "none"; httpOnly?: boolean; maxAge?: number; expires?: Date; }' is not assignable to parameter of type 'CookieOptions'.
  Types of property 'sameSite' are incompatible.
    Type '"lax" | "strict" | "none"' is not assignable to type '"Lax" | "Strict" | "None"'.
      Type '"lax"' is not assignable to type '"Lax" | "Strict" | "None"'. Did you mean '"Lax"'?

And forced to do this instead:

const session = await lucia.createSession(createdUser.userId, {});
const sessionCookie = lucia.createSessionCookie(session.id);

setCookie(ctx, sessionCookie.name, sessionCookie.value, {
  ...sessionCookie.attributes,
  sameSite: "Lax",
});

Suggested change
Change the typing to be in uppercase :
sameSite?: "None" | "Lax" | "Strict"

References :

If it's alright with you, I can create a PR to fix this issue

constant time equal

can you export the constant time equal function that you use in scrypt password util? :)

SameSite cookie typing compatibility with Hono

I'm currently working on integrating Lucia and Oslo with a Hono API and noticed the typing for the SameSite in the Cookie is not compatible with one used by Hono, when looking at the documentation on MDN website it seems that Hono are using the same one as MDN documentation.

Example

This gives a type error :

const session = await lucia.createSession(createdUser.userId, {});
const sessionCookie = lucia.createSessionCookie(session.id);

setCookie(ctx, sessionCookie.name, sessionCookie.value, {
  ...sessionCookie.attributes,
});
Argument of type '{ secure?: boolean; path?: string; domain?: string; sameSite?: "lax" | "strict" | "none"; httpOnly?: boolean; maxAge?: number; expires?: Date; }' is not assignable to parameter of type 'CookieOptions'.
  Types of property 'sameSite' are incompatible.
    Type '"lax" | "strict" | "none"' is not assignable to type '"Lax" | "Strict" | "None"'.
      Type '"lax"' is not assignable to type '"Lax" | "Strict" | "None"'. Did you mean '"Lax"'?

And forced to do this instead:

const session = await lucia.createSession(createdUser.userId, {});
const sessionCookie = lucia.createSessionCookie(session.id);

setCookie(ctx, sessionCookie.name, sessionCookie.value, {
  ...sessionCookie.attributes,
  sameSite: "Lax",
});

Suggested change
Change the typing to be in uppercase :
sameSite?: "None" | "Lax" | "Strict"

References :

If it's alright with you, I can create a PR to fix this issue

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.