Skip to main content

Ask visitors to sign in

Goal​

Turn a portal that anyone can open into one where a visitor signs in first, so your screens can show each person their own records rather than the same page to everybody.

Before you start​

  • A portal you have already published. See Publish an app as a portal.
  • Somebody who runs your Parsware installation has set up email sending. Signing up sends a confirmation link, and without email nobody can finish creating an account.

Steps​

  1. Open your solution, choose Portals, and open the portal.
  2. Change Who can open it from Anyone to People who sign in.
  3. Press Save.

That is the whole change. The next person to open the address gets a sign-in form instead of your app.

What a visitor sees​

A sign-in form, and nothing of your app until they have signed in. Your screens are not drawn behind it — the page is the form.

Unless you say otherwise, the form is the platform's, and deliberately plain. If you would rather it looked like the rest of your site — and keep a landing page open to everyone — you can draw it yourself: see Draw your own sign-in page.

From that form somebody can:

  • Sign in, with the address and password they already have here.
  • Create an account. They fill in a name, an address and a password — the password twice, so a typo cannot lock them out of the account they just made — and we email them a link. They are not signed in yet — they open the link, then sign in.
  • Enter a code, if they have turned on an authenticator app. The form asks for it only when the account has one.
  • Say they have forgotten their password, and get a link to choose a new one. See below.
The link comes back to your portal's front door

A confirmation link lands on your portal's own address, not on a separate page — and so does a password-reset link. So if somebody follows one from their inbox, they arrive at your portal with the right form already showing.

This is why you can safely draw a screen called anything you like — the platform does not reserve /confirm-email, /reset-password or any other name for itself.

If somebody forgets their password​

They press Forgotten your password? on the sign-in form, give their address, and we email them a link. The link brings them back to your portal, asks for a new password twice, and then sends them to sign in with it.

There is nothing for you to build and nothing for you to do. That matters more on a portal than anywhere else: your portal has no support desk of ours behind it, and you cannot reset a visitor's password for them — so this is their only way back in, and it has to work without anybody being asked.

We never say whether an address has an account

The page answers the same way whether or not there is an account for the address somebody typed: "if an account exists for it, a link is on its way."

That is deliberate. A form anybody on the internet can reach, which said "no account here", would be a way to find out which of your customers are registered — one address at a time. The cost is that somebody who mistypes their address waits for a message that will never come, which is why the wording says if.

Two things happen when they save the new password, and both are worth knowing:

  • Every session that account had ends — on every device, not just the one they are using. A password is reset either because it was forgotten or because somebody else has it, and this is the answer to the second case.
  • Their address counts as confirmed, because the link went to their inbox and came back. So somebody who signed up, never opened the confirmation message, and then reset their password can sign in.

Somebody who still knows their password and simply wants a different one uses the same route: there is no "change my password" on a portal.

If somebody is invited to a company​

A portal account can belong to a company, and somebody is put into one by being invited to it. The message carries a link, and on your portal that link lands on the front door — the same address as a confirmation link and a password-reset link. Your portal deals with it:

  • Somebody already signed in joins straight away, and is told which company they have joined.
  • Somebody who is not signed in sees the sign-in form with You have been invited above it. They sign in — or create an account and confirm their address first — and the invitation is still waiting when they get back. They never have to go and find the message again.

Joining changes what your screens answer immediately: the session is re-issued for the company they just joined, so portalCustomerId() returns it on the very next read.

An invitation only works for the address it was sent to

Somebody signed in as anybody else is told which address it was for, and offered a way to sign out and come back as that account.

That is what stops a forwarded message being a way into a company nobody invited its reader to — and forwarding a message is exactly what people do with anything that looks like an action item.

Inviting is drawn by you, and the call is the platform's

A company's Owner invites colleagues from a screen you draw: a text box, a button, and invitePerson(...). There is no People page inside the platform, and the invitation itself is not a record operation — it is one of six calls the platform supplies because no Custom API could make them. See Let visitors run their own company.

What your screens can do once somebody is signed in​

Show who they are. A caption bound to user.name or user.email shows the signed-in person, exactly as it does in an app inside the platform. An image bound to user.photo shows their photo if they have one. The same drawing works in both places — you do not draw a portal version.

Let them sign out. A button whose action is Sign out ends the session and returns them to your portal's front door. On a portal that anyone can open, that button reports a problem instead, because there is nothing to sign out of.

Show each person their own records. This is the point of signing in, and it happens in your Custom API, not on the screen. When a signed-in visitor loads a screen, their identity travels with the request, and your API's script can read it:

// Who is asking — read from their signed-in session, never from the request.
var customerId = portalCustomerId();

// Only the orders belonging to the company they are a member of.
var rows = runQuery({
entity: 'par_order',
select: ['par_name', 'par_placed_on', 'par_amount'],
filter: { connector: 'And', conditions: [
{ field: 'par_customer', operator: 'Equals', value: customerId }
] }
});

setOutput('rows', rows);
setOutput('total', rows.length());

portalCustomerId() reads the company out of the visitor's own session. There is no way for the page to send you a different one, which is what keeps one customer out of another's records.

The filter is yours to write, and nothing checks that you wrote it

An API that does not filter answers every row to every signed-in visitor. Signing somebody in tells you who they are; it does not narrow what your script returns.

Write the filter in the script, and read it again before you tick Published.

Who can create an account​

Anyone who can reach the address. Signing in is not the same as being invited: the form has a Create an account link, and somebody who uses it gets an account with no company attached to it.

What that account can then see is whatever your Custom APIs answer for somebody with no company — which, if your scripts filter the way the example above does, is nothing. That is the right default: a stranger with an account is still a stranger.

They get a company by starting one or by being invited to one, both of which happen on screens you draw: see Let visitors run their own company.

Turning it back off​

Change Who can open it back to Anyone and save. The address opens straight into your app again, and any session somebody had stops counting immediately — nothing keeps honouring an old sign-in on a portal that no longer has any.

The accounts themselves are not deleted. You can see them under Portal users.

Letting them change things​

Signing in is what makes writing possible: a visitor can create, change and delete records once you add a row for each to What it can read. See Let visitors save changes.