web-dev-qa-db-fra.com

de toute façon pour configurer les identifiants npm sur `npm login` sans lire les entrées de STDIN?

J'essaie d'automatiser npm publish dans un conteneur de menu fixe, mais j'ai eu des problèmes lorsque la commande $npm login essaie de lire le nom d'utilisateur et l'adresse électronique à partir des invites:

npm login << EOF
username
password
email
EOF

cela fonctionne en terminal bash mais pas en conteneur sans STDIN ouvert et affiche le message d'erreur suivant:

Username: Password: npm ERR! cb() never called!
npm ERR! not ok code 0

Selon npm-adduser :

Le nom d'utilisateur, le mot de passe et l'adresse électronique sont lus à partir des invites.

Alors, comment puis-je exécuter npm login sans STDIN ouvert?

25
shawnzhu

TL; DR: Effectuer une demande HTTP directement au registre:

TOKEN=$(curl -s \
  -H "Accept: application/json" \
  -H "Content-Type:application/json" \
  -X PUT --data '{"name": "username_here", "password": "password_here"}' \
  http://your_registry/-/user/org.couchdb.user:username_here 2>&1 | grep -Po \
  '(?<="token": ")[^"]*')

npm set registry "http://your_registry"
npm set //your_registry/:_authToken $TOKEN

Raisonnement

En coulisse, npm adduser adresse une requête HTTP au registre. Au lieu de forcer adduser à se comporter comme vous le souhaitez, vous pouvez adresser la demande directement au registre sans passer par le cli, puis définir le jeton d'authentification avec npm set.

Le code source suggère que vous pouvez envoyer une requête PUT à http://your_registry/-/user/org.couchdb.user:your-username avec la charge suivante

{
  name: username,
  password: password
}

et cela créerait un nouvel utilisateur dans le registre.

Merci beaucoup à @shawnzhu pour avoir trouvé une approche plus propre pour résoudre le problème.

23
danielepolencic

Un script attendu a fonctionné pour moi. Vous devez vous assurer que expect est installé, cette commande devrait le faire pour Ubuntu:

apt-get install expect-dev

Votre script pourrait ressembler à ceci (npm_login_expect):

#!/usr/bin/expect -f

# set our args into variables
set i 0; foreach n $argv {set "p[incr i]" $n}

set timeout 60
#npm login command, add whatever command-line args are necessary
spawn npm login
match_max 100000

expect "Username"    
send "$p1\r"

expect "Password"
send "$p2\r" 

expect "Email"
send "$p3\r"

expect {
   timeout      exit 1
   eof
}

Et puis appelez ça comme ça:

expect -f npm_login_expect myuser mypassword "[email protected]"
7
Ted Elliott

J'ai adopté une approche légèrement différente qui semble fonctionner encore très bien. Pour commencer, vous aurez besoin d'un jeton d'authentification. Ceci est facilement accessible en exécutant localement npm adduser, puis en récupérant le jeton généré dans votre ~/.npmrc situé dans votre dossier utilisateur. Pour être authentifié sur votre serveur ci, ce jeton d’authentification doit être ajouté à l’URL du registre dans le .npmrc de l’utilisateur (similaire à ce qu’il était localement), pas le .npmrc situé dans le référentiel. Celles-ci ont donc bien fonctionné comme étapes de script dans mon Configuration CI

- echo "//<npm-registry>:8080/:_authToken=$AUTH_TOKEN" > ~/.npmrc
- npm publish

où AUTH_TOKEN est stocké en tant que variable secrète dans vos paramètres . Un bon moyen de tester cela consiste à remplacer npm publish par npm whoami pour tester et vous assurer qu'il vous a connecté avec succès.

Voici toute ma configuration de publication

publish:
  stage: deploy
  only:
    - tags
  script:
    - yarn run build
    - echo "//<npm-registry>:8080/:_authToken=$NPME_AUTH_TOKEN" > ~/.npmrc
    - npm publish
    - echo 'Congrats on your publication!'

J'utilise gitlab-ci mais je ne vois pas pourquoi cela ne s'appliquerait à aucune application ci.

5
Bryson Reynolds

Difficile de croire qu'après tout ce temps, il n'y a toujours pas de solution pour la connexion npm. Bien sûr, vous pouvez saisir un jeton une fois et l’utiliser pour tous vos besoins en matière de CI, mais qu’en est-il de la sécurité d’un jeton qui n’expire jamais? Et si un jour les administrateurs décidaient que les jetons devaient expirer? 

Ci-dessous ma solution javascript hacky utilisant le package npm-registry-client. Il suffit de passer un argument de chaîne json, il se connectera et écrira un fichier .npmrc dans votre répertoire actuel. Pour vous déconnecter, utilisez npm logout comme d'habitude.

var client = new (require('npm-registry-client'))({});
var std_in = JSON.parse(process.argv[2]);

if (std_in.uri === undefined) {
    console.error('Must input registry uri!');
    return;
}

// fix annoying trailing '/' thing in registry uri
if (std_in.uri[std_in.uri.length - 1] !== '/') {
    std_in.uri = std_in.uri + '/';
}

if (std_in.scope === undefined) {
    console.error('Must input scope!');
    return;
    //std_in.scope = '@my-scope'; // or add default scope of your own
}

if (std_in.scope[0] !== '@') {
    std_in.scope = '@' + std_in.scope;
}

client.adduser(std_in.uri, std_in.params, function(err, data, raw, res) {
    if (err) {
        console.error(err);
        return;
    } 
    require('fs').writeFileSync('.npmrc', `${std_in.scope}:registry=${std_in.uri}\n//${(std_in.uri.split('//'))[1]}:_authToken=${data.token}`);
});

Exemple d'entrée:

{ 
    "uri": "https://my-nmp.reg",
    "scope": "@my-scope",
    "params": {
        "auth": {
            "username": "secret-agent",
            "password": "12345",
            "email": "[email protected]"
        }
    }
}
2
Alexander F.

Cela s'appuie sur la réponse d'Alexander F. Ceci est juste une version simplifiée du code qu'il a fourni, mélangé avec l'exemple de code fourni par npm-registry-client .

"use strict";

var RegClient = require('npm-registry-client')
var client = new RegClient()
var uri = "https://registry.npmjs.org/npm"
var params = {timeout: 1000}

var username = 'my.npm.username'
var password = 'myPassword'
var email = '[email protected]'

var params = {
  auth: {
    username,
    password,
    email
  }
};

client.adduser(uri, params, function (error, data, raw, res) {
  if(error) {
    console.error(error);
    return;
  }
  console.log(`Login succeeded`);
  console.log(`data: ${JSON.stringify(data,null,2)}`);
  console.log(`NPM access token: ${data.token}`);
});
1
Chris Troutner

npm-cli-login vous permet de vous connecter à NPM sans STDIN.

Afin d'installer run

npm install -g npm-cli-login

exemple d'utilisation: -

npm-cli-login -u Nom d'utilisateur -p Mot de passe -e [email protected] -r https: // votre-lien-registre-privé

1
Arun Dhiman

Vous pouvez utiliser un script attendu à la place ou écrire un script de noeud qui utilise pty.js .

0
mscdex

Pour la solution 2 exposée par ke_wa dans ce poste dupliqué a fonctionné.

Écraser:

export NPM_USERNAME=mUs34
export NPM_PASSWORD=mypassW0rD
export [email protected]
npm adduser<<!
$NPM_USERNAME
$NPM_PASSWORD
$NPM_EMAIL
!
0
l.cotonea

Une solution simple configure l'utilisateur et le mot de passe dans le ~/.npmrc

@jfrog:registry=http://localhost:8081/artifactory/api/npm/npm-local/
//localhost:8081/artifactory/api/npm/npm-local/:_password=cGFzc3dvcmQ=
//localhost:8081/artifactory/api/npm/npm-local/:username=admin
//localhost:8081/artifactory/api/npm/npm-local/:[email protected]
//localhost:8081/artifactory/api/npm/npm-local/:always-auth=true

Cela fonctionne également pour spécifier le jeton d'authentification au lieu du mot de passe

Je le fais comme ça:

echo "@my:registry https://artifactory.my.io/artifactory/api/npm/npm-release-local/" >> ~/.npmrc
echo "//artifactory.my.io/artifactory/api/npm/npm-release-local/:_password=${ARTIFACTORY_API_KEY}" >> ~/.npmrc
echo "//artifactory.my.io/artifactory/api/npm/npm-release-local/:username=${ARTIFACTORY_USERNAME}" >> ~/.npmrc
echo "//artifactory.my.io/artifactory/api/npm/npm-release-local/:[email protected]" >> ~/.npmrc
echo "//artifactory.my.io/artifactory/api/npm/npm-release-local/:always-auth=true" >> ~/.npmrc

Recommandé par JFrog https://www.jfrog.com/confluence/display/RTF/npm+Registry#npmRegistry-UsingLoginCredentials

0
dres