UNPKG

@okta/stormpath-migration

Version:

Migration tool to import Stormpath data into an Okta tenant

66 lines (58 loc) 1.88 kB
/*! * Copyright (c) 2017, Okta, Inc. and/or its affiliates. All rights reserved. * The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.") * * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0. * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and limitations under the License. */ function splitIdentifier(mcf) { const index = mcf.indexOf('$', 1); const identifier = mcf.slice(1, index); const content = mcf.slice(index + 1); return [identifier, content]; } function stormpath1(content) { const [salt, value] = content.split('$'); return { algorithm: 'STORMPATH1', salt, value }; } // More detail on Bcrypt format: // https://en.wikipedia.org/wiki/Bcrypt function bcrypt(content) { const [cost, saltHash] = content.split('$'); // First 22 characters is the salt const salt = saltHash.slice(0, 22); // Last 31 characters is the hash const hash = saltHash.slice(22); return { algorithm: 'BCRYPT', workFactor: Number(cost), salt, value: hash } } /** * Converts an MCF formatted string to a password hash described in: * https://oktawiki.atlassian.net/wiki/display/EJ/One+Pager%3A+Import+User+Password+by+Hash * @param {String} mcf mcf formatted string */ function convertMCF(mcf) { const [identifier, content] = splitIdentifier(mcf); switch (identifier) { case 'stormpath1': return stormpath1(content); case '2a': return bcrypt(content); default: // Identifier not currently supported return { algorithm: identifier }; } } module.exports = convertMCF;