pnp / pnpjs

Fluent JavaScript API for SharePoint and Microsoft Graph REST APIs
https://pnp.github.io/pnpjs/
Other
763 stars 304 forks source link

Cannot fetch / get files from spfx webpart for visitor access #3161

Open Muthusivam-saip opened 1 week ago

Muthusivam-saip commented 1 week ago

What version of PnPjs library you are using

2.x (No longer supported)

Minor Version Number

11.0

Target environment

SharePoint Framework

Additional environment details

Nodejs 10.8.1 with spfx frame work

Question/Request

when user with owner/member group access can see the files in spfx frame work , but user with visitor access cannot fetch the file , i checked the folders and files visitor user can see files at directory ("site Assets") but not in the webpart


private async fetchAlerts(): Promise<IFileInfo[]> {
    try {
      const hasPermission = await sp.web.lists.getByTitle("Site Assets").currentUserHasPermissions(PermissionKind.ViewListItems);
      if (!hasPermission) {
        console.error("User does not have permission to view items.");
        alert("User does not have permission to view items.");
        return [];
      }

      const items = await sp.web.folders.getByName("SiteAssets").files.get();
      console.log('items in fetch alerts', items);
      return items;
    } catch (error) {
      console.error("Error retrieving items:", error);
      return [];
    }
  }
public async render(): Promise<void> {
    this.domElement.innerHTML = `
      <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">
      <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
      <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
      <div class="input-group mb-3">
        <input type="text" class="form-control" id="searchBox" placeholder="Search by name or extension" aria-label="Search" aria-describedby="button-addon2">
      </div>
      <div id="fileUrlsContainer"></div>`;

    const items = await this.fetchAlerts();

    const searchBox = this.domElement.querySelector('#searchBox') as HTMLInputElement;
    searchBox?.addEventListener('input', () => {
      const searchTerm = searchBox.value;
      this.renderFileUrls(items, searchTerm);
    });

    this.renderFileUrls(items);
    console.log('items',items);
    console.log('searchBox',searchBox);
  }

am i missing any important auth process

i checked the permission levels at folder it is atleast in read permission enabled for all users

patrick-rodgers commented 1 week ago

What's the error?

Muthusivam-saip commented 6 days ago

hi thanks for responding back

below is the error im facing

" Failed to load resource: the server responded with a status of 403 () list-pdf-web-part_37241b8df0db3f556764.js:1 Error retrieving items: Error: Error making HttpClient request in queryable [403] ::> {"odata.error":{"code":"-2147024891, System.UnauthorizedAccessException","message":{"lang":"en-US","value":"Access denied."}}}"

juliemturner commented 5 days ago

Where are you initializing your sp object... given the version of nodejs and the version of pnpjs I assume you're not using a recent version of SPFx?

patrick-rodgers commented 5 days ago

So...access denied is access denied. That's not a library issue - can you show where you initialize this.sp as requested by Julie?

Muthusivam-saip commented 5 days ago

Hi , below shows the code snippets

public async onInit(): Promise { sp.setup({ spfxContext: this.context as unknown as ISPFXContext, sp: { baseUrl: ${window.location.protocol}//${window.location.hostname}/${this.properties.sitePath} } });

const currentUser = await sp.web.currentUser.get();
const userEmail = currentUser.Email;

// Grant read permissions to the current user
await this.grantReadPermissions(userEmail);

const combinedData = await this.fetchAndCombineData();
this.renderFileUrls(combinedData);

this.domElement.innerHTML = `
  <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
  <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-YvpcrYf0tY3lHB60NNkmXc5s9fDVZLESaAA55NDzOxhy9GkcIdslK1eN7N6jIeHz" crossorigin="anonymous"></script>
`;
return super.onInit();

}

private async grantReadPermissions(userEmail: string): Promise { try { // Get the user by email const user = await sp.web.siteUsers.getByEmail(userEmail).get();

  // Get the Site Assets library
  const list = await sp.web.lists.getByTitle("Site Assets");

  // Break role inheritance if needed
  await list.breakRoleInheritance(true);

  // Get the role definition for Read
  const readRoleDef = await sp.web.roleDefinitions.getByName("Read").get();

  // Add the user to the role assignment with read permissions
  await list.roleAssignments.add(user.Id, readRoleDef.Id);

  console.log(`Read permissions granted to ${userEmail}`);
} catch (error) {
  console.error("Error granting permissions:", error);
}

}

Muthusivam-saip commented 5 days ago

also i want to mention a important log here

Access to XMLHttpRequest at ' https://m365.cloud.microsoft/apc/trans.gif?[redacted]' from origin ' https://xyz.sharepoint.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.