Skip to content
Syno Package Land
Language: English

Standalone login

The login capability gives the app its own session. When a DSM id cookie is available for the same host name, the app exchanges it for an app session. Otherwise it shows a sign-in page that checks the account, password and OTP code against DSM. The app stores no password or OTP code. It needs no administrator setup and no Node.js on the NAS.

It identifies the user. It does not give the app a File Station session: see Files.

New project (the Vue UI is the default):

Terminal window
synopkgland init -t native-go --with login my-login

Existing project:

Terminal window
synopkgland add login

Both set this in dsm-package.yaml:

capabilities:
identity: standalone

standalone is the only value.

CombinationResult
Plain UI (--ui plain, no ui.build)Not supported. check reports CAPABILITY_COMBINATION_INVALID and init refuses it
Binary backendCAPABILITY_UNSUPPORTED
armv7Allowed

The generated Vue app shows its sign-in page whenever login is on and there is no session. The page needs HTTPS in the browser.

  1. DSM cookie. If the browser sends a valid DSM id cookie, the backend validates it with DSM’s native authenticate.cgi, preserving the browser’s client address, and issues an app session. This needs HTTPS. Cookies belong to a host name, not a port, so an app on another port of the same host name receives the cookie. An IP address and a DNS name are different host names. A cross-site frame cannot be assumed to receive DSM cookies.
  2. Sign-in page. Without a usable DSM cookie, the user enters the DSM account and password. If DSM asks for a second factor, the page asks for the OTP code and sends the request again. The backend signs in to DSM once to prove the identity and then ends that DSM session right away. It never keeps it.

A disabled account, a wrong password and an account that may not sign in are refused with different codes, see Troubleshooting.

The app session identifies the user. For every method except app.status and greeting.get, the backend checks again that a live DSM id cookie of the same user is present. A request without it fails with session_revalidation_required, or dsm_session_required for file and job-import methods. A cookie for another user ends the session. So a password sign-in alone opens only those two methods. For anything else, the user must also be signed in to DSM on the same host name.

Each successful check extends the session by the full lifetime.

All are public routes and need a same-origin JSON POST.

MethodParamsResult
identity.status{}{ enabled: true }
identity.session{ bootstrap?: boolean }{ user, uid, expiresAt }. With bootstrap and no app cookie, exchanges the DSM cookie (HTTPS only). The native session check also forwards the request’s X-SYNO-TOKEN when supplied by the DSM window
identity.login{ account, password, otp? }{ user, uid, expiresAt } (HTTPS only)
identity.logout{}{ loggedOut: true } and clears the cookie

createSession(ctx) from @synopackageland/sdk/vue wraps them. It returns enabled, ready, subject, notice, start, call, login, bootstrap, logout and dispose. Use session.call(method, params) instead of ctx.call for your own methods, as the generated App.vue does.

ItemValue
TransportHTTPS for identity.login and for the DSM-cookie exchange
Session lifetime15 minutes, extended by each successful DSM-cookie check
Session cookiespl_session_<16 hex digits>, HttpOnly, Secure, SameSite=Lax, limited to the app’s path
Sign-in attempts5 per account and 20 per client address in one minute. Every attempt counts
SessionsAt most 4096
Time DSM has to answer10 seconds
Credentials acceptedAccount up to 1024 characters, password 4096, OTP 128
RequestsSame origin only. Origin scheme, host and port must match

If the account or its DSM data changes so that the user name stops resolving to the same UID, the session ends.

CodeCauseFix
https_requiredSign-in or the DSM-cookie exchange over plain HTTPOpen the app over HTTPS
invalid_credentialsWrong account or passwordTry again
account_disabledThe DSM account is disabledUse another account
otp_requiredDSM wants a second factorSend the OTP code in otp
login_not_permittedDSM refused the sign-in for any other reasonCheck the account and its sign-in settings in DSM
rate_limited5 attempts for the account or 20 for the address in a minuteWait a minute
cross_originThe request came from another originCall from the app page, not another site
origin_requiredA POST carried neither Origin nor RefererOpen the app again in a current browser
session_requiredNo app session, an expired one, or the DSM cookie did not matchSign in again
session_revalidation_requiredThe method needs the DSM id cookie and the browser did not send itSign in to DSM on the same host name, then retry
dsm_session_requiredSame, for nas.*, bg.browse and bg.jobs.submitSign in to DSM on the same host name
auth_unavailableDSM could not be asked, or 4096 sessions existRetry later

Codes are described in Errors. To keep the app out of reach of some users, use entry as described in Native apps.