Skip to content

SharePointAccessValidator

SharePointAccessValidator is a customer-owned access validation hook that the framework calls before minting or using SharePoint tokens. Implement this interface to enforce your application's authorization rules, such as audit firm membership, assignment checks, SharePoint enablement, and folder scope restrictions.

Import

import {
  SharePointAccessValidator,
  AccessValidationResult,
} from "@modernpath/agent-framework";

Interface

interface SharePointAccessValidator {
  validateAccess(userId: number, auditingId: number): Promise<AccessValidationResult>;
}

AccessValidationResult

interface AccessValidationResult {
  valid: boolean;
  reason?: string;
}
Field Type Description
valid boolean true if the user is authorized to access SharePoint for the given auditing context.
reason string Human-readable reason when valid is false. Included in the error thrown by SharePointAuth.

How It Is Used

SharePointAuth.getAccessToken() calls validateAccess() before every token request (including cached token returns). If validation fails, getAccessToken() throws an error with the provided reason.

sequenceDiagram
    participant Auth as SharePointAuth
    participant AV as AccessValidator
    participant Caller

    Caller->>Auth: getAccessToken(userId, auditingId)
    Auth->>AV: validateAccess(userId, auditingId)

    alt Access granted
        AV-->>Auth: { valid: true }
        Auth-->>Caller: access token
    else Access denied
        AV-->>Auth: { valid: false, reason: "..." }
        Auth-->>Caller: throws Error(reason)
    end

Implementation Example

import { SharePointAccessValidator, AccessValidationResult } from "@modernpath/agent-framework";

class MyAccessValidator implements SharePointAccessValidator {
  constructor(
    private readonly userService: UserService,
    private readonly auditingService: AuditingService,
  ) {}

  async validateAccess(userId: number, auditingId: number): Promise<AccessValidationResult> {
    // 1. Check user exists and is active
    const user = await this.userService.findById(userId);
    if (!user || !user.isActive) {
      return { valid: false, reason: "User not found or inactive" };
    }

    // 2. Check user has SharePoint enabled
    if (!user.sharePointEnabled) {
      return { valid: false, reason: "SharePoint access not enabled for this user" };
    }

    // 3. Check user is assigned to the auditing
    const assignment = await this.auditingService.getAssignment(userId, auditingId);
    if (!assignment) {
      return { valid: false, reason: "User is not assigned to this auditing" };
    }

    // 4. Check auditing has SharePoint configured
    const auditing = await this.auditingService.findById(auditingId);
    if (!auditing?.sharePointSiteId) {
      return { valid: false, reason: "Auditing does not have SharePoint configured" };
    }

    return { valid: true };
  }
}

Simple Allow-All Validator (Development)

const devValidator: SharePointAccessValidator = {
  async validateAccess(_userId, _auditingId) {
    return { valid: true };
  },
};

Wiring with SharePointAuth

import { SharePointAuth } from "@modernpath/agent-framework";

const validator = new MyAccessValidator(userService, auditingService);

const auth = new SharePointAuth(
  {
    tenantId: process.env.AZURE_TENANT_ID!,
    clientId: process.env.AZURE_CLIENT_ID!,
    clientSecret: process.env.AZURE_CLIENT_SECRET!,
    useOnBehalfOfExchange: true,
  },
  tokenProvider,
  validator,
);

// This will call validator.validateAccess() before returning a token
try {
  const token = await auth.getAccessToken(userId, auditingId);
} catch (err) {
  // err.message contains the validation reason
  console.error("Access denied:", err.message);
}