npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@gasboost/auth-app

v0.8.0

Published

Authentication middleware adapter for @gasboost/auth and @gasboost/app.

Downloads

825

Readme

@gasboost/auth-app

@gasboost/auth と @gasboost/app を接続する authentication middleware adapter です。

RPC input とは独立した metadata に session token を含め、RPC 実行前に既存の auth.session.get(token) を利用して session を検証します。

有効な session は AppsScript の state に保存されます。

RPC metadata["@gasboost/auth"]
   ↓
token
   ↓
@gasboost/auth-app
   ↓
auth.session.get(token)
   ↓
Session
   ↓
AppsScript state

@gasboost/app 自体は @gasboost/auth を認識しません。

@gasboost/auth
      ↑
@gasboost/auth-app  →  @gasboost/app

Install

pnpm add @gasboost/auth-app @gasboost/auth @gasboost/app

npm:

npm install @gasboost/auth-app @gasboost/auth @gasboost/app

Auth metadata

@gasboost/app@^5.2.0 の RPC metadata を利用します。 key / schema / validator は frontend と backend で共通の @gasboost/auth-client/metadata が提供します。

import {
  AUTH_METADATA_KEY,
  type AuthMetadata,
} from "@gasboost/auth-client/metadata";

const metadata = {
  [AUTH_METADATA_KEY]: { token } satisfies AuthMetadata,
};

await app.dispatch("updateProfile", { name: "Taro" }, metadata);

handler input は業務入力だけを定義します。 AuthenticatedInput<T> は 0.4.0 で削除しました。 input の token は認証には使いません。旧方式との後方互換性はありません。

@gasboost/client では metadata provider を登録することで、 RPC ごとに token を渡さずに利用できます。 frontend では pnpm add @gasboost/client @gasboost/auth-client で依存を追加します。

import { appsScriptClient } from "@gasboost/client";
import { AUTH_METADATA_KEY } from "@gasboost/auth-client/metadata";

const { client } = appsScriptClient<AppType>({
  metadataProviders: [
    () => {
      const token = getCurrentToken();
      return token ? { [AUTH_METADATA_KEY]: { token } } : undefined;
    },
  ],
});

await client.updateProfile({ name: "Taro" });

session lifecycle 管理には @gasboost/auth-client/appsscript の appsScriptAuth({ client, storage }) と authMetadataProvider(storage) を利用できます。 詳細は auth-client README を参照してください。

Authentication middleware

既存の AppsScriptAuth instance を authentication() に渡します。

session storage や repository を middleware 側で再定義する必要はありません。

import { AppsScript } from "@gasboost/app";
import { AppsScriptAuth } from "@gasboost/auth";
import { authentication } from "@gasboost/auth-app";

const auth = new AppsScriptAuth({
  repository,

  runtime: {
    utilities: Utilities,
    session: Session,
    cacheService: CacheService,
    propertiesService: PropertiesService,
  },

  session: {
    storageType: "cache",
  },
});

const app = new AppsScript().use(authentication(auth));

authentication() は AppsScriptAuth の既存 session API を利用します。

const session = await auth.session.get(token);

有効な session が取得できた場合、middleware はその session を AppsScript state に設定します。

@gasboost/app v5.2 以降では authentication() の適用後、後続 handler の context.state から session が non-nullable として取得できます。

Auth handlers

handlers(auth) は AppsScriptAuth の公開 API を @gasboost/app の RPC handler として登録できる形へ変換します。

import { AppsScript } from "@gasboost/app";
import { AppsScriptAuth } from "@gasboost/auth";
import { authentication, handlers } from "@gasboost/auth-app";

const auth = new AppsScriptAuth({
  repository,
  runtime,
  session: {
    storageType: "cache",
  },
});

const app = new AppsScript().calls(handlers(auth)).use(authentication(auth));

以下の RPC が公開されます。

  • signInEmail
  • signInAppsScript
  • signUpEmail
  • signUpAppsScript
  • getSession
  • signOut

Password Reset が有効な場合は、さらに以下も公開されます。

  • forgotPassword
  • resetPassword

signIn / signUp / Password Reset の input と result の型は @gasboost/auth の既存 API から推論されます。

@gasboost/auth@^0.7.0 で afterSignIn を設定すると、Sign In / Sign Up の email / Apps Script 全 RPC に hooks の戻り値型が伝播します。 @gasboost/auth-client の Consumer Hook も、その RPC 型から結果を推論します。 Firebase の接続例は auth-client README を参照してください。

getSession と signOut は、RPC の単一 object input contract に合わせて以下の形式になります。

client.getSession({
  sessionId: "session-id",
});

client.signOut({
  sessionId: "session-id",
});

signOut / forgotPassword / resetPassword の RPC 成功時の result は JSON として扱える null です(0.5.0 以降)。 @gasboost/auth 側の API 自体は変更されません。

await auth.session.get("session-id");
await auth.signOut.execute("session-id");

Authorization Middleware

authorization() は、authentication(auth) が state に保存した session.userId を使って AppsScriptAuthorization.can() に委譲します。token の再検証、Session Storage へのアクセス、Repository への直接アクセスは行いません。

import {
  authentication,
  authorization as requireAuthorization,
} from "@gasboost/auth-app";

const app = new AppsScript()
  .use(authentication(auth))
  .use(
    requireAuthorization(authorization, {
      project: ["update"],
    }),
  )
  .call("updateProject", updateProject);

許可されない場合は Forbidden を throw します。認証に失敗した場合の Unauthorized とは区別されます。

authorizationHandlers(authorization) は role / permission assignment 用の handler を生成します。

const handlers = authorizationHandlers(authorization);

app.call("assignRole", handlers.role.assign);
app.call("allowPermission", handlers.permission.allow);

これらの handler は強い権限を持つ master operation です。自動登録や暗黙の管理権限付与は行わないため、公開する RPC 名と保護用 middleware は application 側で明示してください。

Authenticated RPC

認証が必要な RPC は authentication(auth) より後に登録します。

import { AppsScript } from "@gasboost/app";
import { authentication } from "@gasboost/auth-app";

const app = new AppsScript()
  .use(authentication(auth))
  .call("getProfile", (_input, context) => {
    const session = context.state.get("session");

    return getProfile(session.userId);
  });

authentication(auth) の通過後は session が state に存在することが型として保証されるため、undefined check は不要です。

クライアント側では metadata provider が token を供給します。

client.getProfile();

追加 input が必要な場合:

const app = new AppsScript().use(authentication(auth)).call(
  "updateProfile",
  (
    input: {
      name: string;
    },
    context,
  ) => {
    const session = context.state.get("session");

    return updateProfile({
      userId: session.userId,
      name: input.name,
    });
  },
);

クライアント:

client.updateProfile({
  name: "Taro",
});

Public RPC

middleware はすべての RPC に認証を要求するわけではありません。

公開 RPC は authentication(auth) より前に登録します。middleware より後の RPC は input の有無にかかわらず認証必須です。

const app = new AppsScript()
  .call("signIn", (input: { email: string; password: string }) => {
    return auth.signIn.email(input);
  })
  .use(authentication(auth));

クライアント側でも token は不要です。

client.signIn({
  email: "[email protected]",
  password: "password",
});

input 自体を持たない公開 RPC も利用できます。

const app = new AppsScript()
  .call("health", () => ({ ok: true }))
  .use(authentication(auth));

Session state

認証に成功すると middleware は取得した session を AppsScript state に設定します。

context.state.set("session", session);

authentication(auth) より後の application handler では、context.state から取得できます。

const app = new AppsScript()
  .use(authentication(auth))
  .call("getProfile", (_input, context) => {
    const session = context.state.get("session");

    session.id;
    session.userId;
    session.createdAt;
    session.expiresAt;

    return getProfile(session.userId);
  });

authentication(auth) が session state を保証するため、後続 handler では session は undefined になりません。

application user が必要な場合は session.userId を利用して application 側で取得します。

const app = new AppsScript()
  .use(authentication(auth))
  .call("getProfile", async (_input, context) => {
    const session = context.state.get("session");
    const user = await userRepository.find(session.userId);

    return user;
  });

@gasboost/auth-app は application User の取得までは担当しません。

Unauthorized

middleware より後に登録されたすべての RPC で auth metadata を検証します。

以下の場合は Unauthorized error になります。

  • auth metadata が存在しない、または object ではない
  • token が存在しない、string ではない、空文字、空白のみ
  • auth.session.get(token) が session を返さない
  • session が期限切れ
throw new Error("Unauthorized");

期限切れ session の判定と削除は @gasboost/auth の既存 session.get() が担当します。

middleware 側で session storage を直接操作することはありません。

Apps Script identity

Session.getActiveUser().getEmail() と application session は別の概念です。

Session.getActiveUser().getEmail()
            ≠
application session

この middleware では application の認証状態を RPC metadata の session token から確認します。

token
  ↓
auth.session.get(token)
  ↓
application Session

Apps Script Active User を application session の代替として扱いません。

Custom state

@gasboost/app v5.2 以降では middleware が追加する state は .use() によって型へ反映されます。

const app = new AppsScript().use(authentication(auth));

authentication(auth) より後の handler では session state が保証されます。

const app = new AppsScript()
  .calls(handlers(auth))
  .call("health", () => ({
    ok: true,
  }))
  .use(authentication(auth))
  .call("getProfile", (_input, context) => {
    const session = context.state.get("session");

    return getProfile(session.userId);
  });

application 独自の state を追加する場合も、対応する middleware を .use() で組み合わせます。

Responsibility

@gasboost/auth-app が担当するもの:

  • 共有 auth metadata contract の解釈
  • RPC metadata から token の取得
  • auth.session.get(token) による session 検証
  • session の AppsScript state への設定
  • invalid token の拒否

担当しないもの:

  • session storage の構築
  • repository の構築
  • User の取得
  • Session.getActiveUser() による identity 解決

これらはそれぞれ @gasboost/auth または application の責務です。

拡張ユーザーの RPC(0.7.0)

AppsScriptAuth の user.data を設定すると、handlers(auth) の4種の SignIn / SignUp と getSession に戻り値の型が自動伝播します。追加設定は不要です。

const app = new AppsScript().calls(handlers(auth));
const restored = await handlers(auth).getSession({ sessionId });
restored?.user.data.permissions; // consumer が user.data で定義した型

getSession は auth.session.getWithUser(id) を呼び、従来の id, userId, createdAt, expiresAt を維持したまま user を追加します。 User の取得・拡張・エラー処理は auth 本体が担当します。 authentication(auth) は引き続き session.get によるセッション検証を行います。

共通の認証エラー処理

authErrorHandler() は 対象 RPC を .calls() / .call() で登録する前に .use() で登録してください。@gasboost/app@^5.5.0 が必要です。

import { AppsScript } from "@gasboost/app";
import { authErrorHandler, authentication, handlers } from "@gasboost/auth-app";

const app = new AppsScript()
  .use(authErrorHandler())
  .calls(handlers(auth))
  .use(authentication(auth))
  .call(
    "someProtectedRpc",
    (_input, context) => context.state.get("session").userId,
  );

handlers(auth)、認証・認可 middleware、Consumer RPC 内で直接呼び出した Auth API の AuthError を、同じ code と message の AppsScriptError に変換します。その他の例外はそのまま再 throw し、RPC 境界で INTERNAL_ERROR と安全な共通メッセージに正規化されます。

フロントエンドでは @gasboost/client@^0.6.0 が復元したエラーを判定します。 @gasboost/auth/errors はブラウザでも安全に import できます。

import { AppsScriptRpcError } from "@gasboost/client";
import { AUTH_ERROR_CODES } from "@gasboost/auth/errors";

try {
  await client.signInEmail({ email, password });
} catch (error) {
  if (
    error instanceof AppsScriptRpcError &&
    error.code === AUTH_ERROR_CODES.INVALID_CREDENTIALS
  ) {
    // 認証情報の再入力など、アプリ側の表示処理
  }
}

@gasboost/auth-client はエラーコードを複製せず、RPC エラーも復元しません。