pnp / pnpjs

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

siteUsers.getByLoginName and getByEmail throwing error when email has single quote #2889

Closed hermilanastacio closed 9 months ago

hermilanastacio commented 10 months ago

What version of PnPjs library you are using

3.x

Minor Version Number

18.0

Target environment

All

Additional environment details

Sharepoint Webpart/Authentication

Question/Request

import { sp } from "@pnp/sp";

public async componentDidMount() { await sp.web.siteUsers.getByLoginName("i:0#.f|membership|camp.o'donnell@contoso.com.au").get() }

OR EVEN

public async componentDidMount() { await sp.web.siteUsers.getByLoginName("i:0#.f|membership|camp.o'donnell@contoso.com.au")() }

I'm getting "The expression "web/siteusers(@vdriscoll@contoso.com.au')" is not valid."

Ps. I tried it in v2 and v3 but same error

Reference: https://github.com/pnp/pnpjs/issues/2874

patrick-rodgers commented 10 months ago

@hermilanastacio - if you encode the value before passing it - does that resolve your issue? I.e. you can replace the ' with '' (two single quotes). We'll have to trace through and cover all the various code paths to understand how best to address this.

hermilanastacio commented 10 months ago

@patrick-rodgers tried to encode it and also replacing ' with '' it but it throws error 400 (Bad Request), btw it works fine on regular email format tho, only on emails with single quote for some reason.

image

bcameron1231 commented 10 months ago

I am unable to reproduce the issue using double single quotes.

//works
await sp.web.siteUsers.getByEmail("camp.o''donnell@contoso.com.au")();
//works
await sp.web.siteUsers.getByLoginName("i:0#.f|membership|camp.o''donnell@contoso.com.au")()

However, The error you just posted is coming from _api/web/ensureuser not from these methods. Are you using sp.web.ensureUser() somewhere?

hermilanastacio commented 10 months ago

Here's the actual error message that I'm getting. image

Endpoint -> https://{tenant}/sites/workplace/_api/web/siteusers(@)?@v=%27i%3A0%23.f%7Cmembership%7Ccamp.o%27donnel%40contoso.com.au%27

hermilanastacio commented 10 months ago

Seems like in the url https://{tenant}/sites/workplace/_api/web/siteusers(@v)?@v=%27i%3A0%23.f%7Cmembership%7Ccamp.o%27donnel%40contoso.com.au%27

The value of @v= is the encoded login name 'i:0#.f|membership|camp.o'donnel@contoso.com.au' with open and close single quote, and I assume it's getting conflict with single quote in the email.

image

patrick-rodgers commented 10 months ago

Yes, that is what is happening, were you able to test encoding it as suggested using two single quotes?

hermilanastacio commented 10 months ago

@patrick-rodgers yes, I tried it and it return an error The query string "loginName" is missing or invalid. same as above

hermilanastacio commented 10 months ago

I am unable to reproduce the issue using double single quotes.

//works
await sp.web.siteUsers.getByEmail("camp.o''donnell@contoso.com.au")();
//works
await sp.web.siteUsers.getByLoginName("i:0#.f|membership|camp.o''donnell@contoso.com.au")()

However, The error you just posted is coming from _api/web/ensureuser not from these methods. Are you using sp.web.ensureUser() somewhere?

Yes I am, but that doesn't throw error on my end image

bcameron1231 commented 10 months ago

Yes I am, but that doesn't throw error on my end

Based on the photo you sent before it was throwing an error.

Looking back at your Postman photo, that is erroring because you're still only using a single quote, not a double single quote, thus you're getting the queryString loginName is invalid error.

As for the getByLoginName() in your latest photo (you're using V2), Yes I can confirm this doesn't work in V2. It will work in V3 when using double single quotes ( have tested this), and we recommend using V3.

To recap on my testing V2 - getByEmail() with double single quote - works V2 - getByLoginName() - will not work as implemented V3 - getByEmail() - with double single quote - works V3 - getByLogin() - with double single quote - works.

Recommendation to try again. Use V3, and use single double quotes. I have tested this and it works.

hermilanastacio commented 9 months ago

@bcameron1231 , I used v3 and I tried these different text formats

image

but still, no luck. Could you please share how you do it?

bcameron1231 commented 9 months ago

Can you confirm what you're using? It looks like you're using double quotes. For example #3 and #4.

You should use two single quotes in a row.

hermilanastacio commented 9 months ago

@bcameron1231

1 I used single quote and just added (/) as escape character in email

2 I used double quote for start and end of string

3 I used double single quote and replace the single quote with double quote instead

4 I tried string literal, I used backtick (`) character and replace the single quote with double quote instead

5 I just tried string literal, I used backtick (`) character

these are the formats I tried but still, no luck

bcameron1231 commented 9 months ago

So #4 to confirm should be backtick, and the single quote between the name should be replaced with two single quotes, not a double quote.

I.e you just need to add 1 more single quote.

hermilanastacio commented 9 months ago

@bcameron1231 tried it and I got same error on item #3

bcameron1231 commented 9 months ago

I think your issue might still be coming from ensureUser and not getByLoginName. For clarity, ensureUser works without having to encode or change the loginname. getByEmail and getByLoginName however need to be modified as we've talked about. Here is y working code.

//no change to login name. Single quote, wrap login by double quotes
const ensureUser = await sp.web.ensureUser("i:0#.f|membership|tim.o'dare@cameroncode.onmicrosoft.com");
// Two single quotes between name, wrapped in double quotee
const user = await sp.web.siteUsers.getByLoginName("i:0#.f|membership|tim.o''dare@cameroncode.onmicrosoft.com")();

image

image

image

hermilanastacio commented 9 months ago

@bcameron1231 this code of yours works on v3

image

need to change the single quote (') to double single quote ('') instead. Though my add to list function is not being pushed through after using v3 for some reason.

Anyways, now, I was able to get the right id of user with single quote in their email. Thank you so much for your help!

bcameron1231 commented 9 months ago

Glad we were able to resolve it!

github-actions[bot] commented 9 months ago

This issue is locked for inactivity or age. If you have a related issue please open a new issue and reference this one. Closed issues are not tracked.