Could i login solid pod automatically without opening the solid login page?

thanks for your reply :smiley:I’m not developping an in-browser app.In fact,i’m working with NodeJS.I had created an express application.I find a library provides access to Solid: GitHub - solid/solid-node-client: a nodejs client for Solid ,but when i try to authentication for NSS-Style Pods, there a new error i didn’t find the way to solve it :cry: :cry:


app.js

var SolidNodeClient = require('solid-node-client');
const client = new SolidNodeClient.SolidNodeClient();
async function getlogin(){
  try {
    let session = await client.login({
    idp : "https://solidcommunity.net", // e.g. https://solidcommunity.net
    username : "myname",
    password : "mypassword",
  });
  if( session.isLoggedIn ) {let webid = await client.fetch(session.webId); console.log(webid); }
} catch (e) {
    console.log(e, "ERROR");
}

TokenRequester.js

"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const tsyringe_1 = require("tsyringe");
const url_parse_1 = __importDefault(require("url-parse"));
const form_urlencoded_1 = __importDefault(require("form-urlencoded"));
let TokenRequester = class TokenRequester {
    constructor(storageUtility, issuerConfigFetcher, fetcher, dpopHeaderCreator, joseUtility) {
        this.storageUtility = storageUtility;
        this.issuerConfigFetcher = issuerConfigFetcher;
        this.fetcher = fetcher;
        this.dpopHeaderCreator = dpopHeaderCreator;
        this.joseUtility = joseUtility;
    }
    async request(localUserId, body) {
        const [issuer, clientId, clientSecret] = await Promise.all([
            this.storageUtility.getForUser(localUserId, "issuer", true),
            this.storageUtility.getForUser(localUserId, "clientId", true),
            this.storageUtility.getForUser(localUserId, "clientSecret")
        ]);
        const issuerConfig = await this.issuerConfigFetcher.fetchConfig(new url_parse_1.default(issuer));
        if (body.grant_type &&
            (!issuerConfig.grantTypesSupported ||
                !issuerConfig.grantTypesSupported.includes(body.grant_type))) {
            throw new Error(`The issuer ${issuer} does not support the ${body.grant_type} grant`);
        }
        if (!issuerConfig.tokenEndpoint) {
            throw new Error(`This issuer ${issuer} does not have a token endpoint`);
        }
        const tokenRequestInit = {
            method: "POST",
            headers: {
                DPoP: await this.dpopHeaderCreator.createHeaderToken(issuerConfig.tokenEndpoint, "POST"),
                "content-type": "application/x-www-form-urlencoded"
            },
            body: form_urlencoded_1.default({
                ...body,
                client_id: clientId
            })
        };
        if (clientSecret) {
            tokenRequestInit.headers.Authorization = `Basic ${this.btoa(`${clientId}:${clientSecret}`)}`;
        }
        const tokenResponse = await (await this.fetcher.fetch(issuerConfig.tokenEndpoint, tokenRequestInit)).json();
        if (!(tokenResponse &&
            tokenResponse.access_token &&
            tokenResponse.id_token &&
            typeof tokenResponse.access_token === "string" &&
            typeof tokenResponse.id_token === "string" &&
            (!tokenResponse.refresh_token ||
                typeof tokenResponse.refresh_token === "string"))) {
            throw new Error("IDP token route returned an invalid response.");
        }
        await this.storageUtility.setForUser(localUserId, "accessToken", tokenResponse.access_token);
        await this.storageUtility.setForUser(localUserId, "idToken", tokenResponse.id_token);
        await this.storageUtility.setForUser(localUserId, "refreshToken", tokenResponse.refresh_token);
        const decoded = await this.joseUtility.decodeJWT(tokenResponse.access_token);
        if (!decoded || !decoded.sub) {
            throw new Error("The idp returned a bad token without a sub.");
        }
        await this.storageUtility.setForUser(localUserId, "webId", decoded.sub);
    }
    btoa(str) {
        return Buffer.from(str.toString(), "binary").toString("base64");
    }
};
TokenRequester = __decorate([
    tsyringe_1.injectable(),
    __param(0, tsyringe_1.inject("storageUtility")),
    __param(1, tsyringe_1.inject("issuerConfigFetcher")),
    __param(2, tsyringe_1.inject("fetcher")),
    __param(3, tsyringe_1.inject("dpopHeaderCreator")),
    __param(4, tsyringe_1.inject("joseUtility")),
    __metadata("design:paramtypes", [Object, Object, Object, Object, Object])
], TokenRequester);
exports.default = TokenRequester;
//# sourceMappingURL=TokenRequester.js.map