Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New providers #527

Merged
merged 5 commits into from
Mar 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [unreleased]

## [13.2.0] - 2023-03-29

### Changed

- Updates the example app to also initialise the dashboard

### Added

- Login with bitbucket and gitlab (single tenant only)

## [13.1.5] - 2023-03-17

### Fixes
Expand Down
4 changes: 4 additions & 0 deletions lib/build/recipe/thirdparty/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ export default class Wrapper {
static Apple: typeof import("./providers/apple").default;
static Discord: typeof import("./providers/discord").default;
static GoogleWorkspaces: typeof import("./providers/googleWorkspaces").default;
static Bitbucket: typeof import("./providers/bitbucket").default;
static GitLab: typeof import("./providers/gitlab").default;
}
export declare let init: typeof Recipe.init;
export declare let Error: typeof SuperTokensError;
Expand All @@ -41,4 +43,6 @@ export declare let Facebook: typeof import("./providers/facebook").default;
export declare let Apple: typeof import("./providers/apple").default;
export declare let Discord: typeof import("./providers/discord").default;
export declare let GoogleWorkspaces: typeof import("./providers/googleWorkspaces").default;
export declare let Bitbucket: typeof import("./providers/bitbucket").default;
export declare let GitLab: typeof import("./providers/gitlab").default;
export type { RecipeInterface, User, APIInterface, APIOptions, TypeProvider };
6 changes: 5 additions & 1 deletion lib/build/recipe/thirdparty/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ var __importDefault =
return mod && mod.__esModule ? mod : { default: mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.GoogleWorkspaces = exports.Discord = exports.Apple = exports.Facebook = exports.Github = exports.Google = exports.getUserByThirdPartyInfo = exports.getUsersByEmail = exports.getUserById = exports.signInUp = exports.Error = exports.init = void 0;
exports.GitLab = exports.Bitbucket = exports.GoogleWorkspaces = exports.Discord = exports.Apple = exports.Facebook = exports.Github = exports.Google = exports.getUserByThirdPartyInfo = exports.getUsersByEmail = exports.getUserById = exports.signInUp = exports.Error = exports.init = void 0;
const recipe_1 = __importDefault(require("./recipe"));
const error_1 = __importDefault(require("./error"));
const thirdPartyProviders = __importStar(require("./providers"));
Expand Down Expand Up @@ -124,6 +124,8 @@ Wrapper.Facebook = thirdPartyProviders.Facebook;
Wrapper.Apple = thirdPartyProviders.Apple;
Wrapper.Discord = thirdPartyProviders.Discord;
Wrapper.GoogleWorkspaces = thirdPartyProviders.GoogleWorkspaces;
Wrapper.Bitbucket = thirdPartyProviders.Bitbucket;
Wrapper.GitLab = thirdPartyProviders.GitLab;
exports.init = Wrapper.init;
exports.Error = Wrapper.Error;
exports.signInUp = Wrapper.signInUp;
Expand All @@ -136,3 +138,5 @@ exports.Facebook = Wrapper.Facebook;
exports.Apple = Wrapper.Apple;
exports.Discord = Wrapper.Discord;
exports.GoogleWorkspaces = Wrapper.GoogleWorkspaces;
exports.Bitbucket = Wrapper.Bitbucket;
exports.GitLab = Wrapper.GitLab;
15 changes: 15 additions & 0 deletions lib/build/recipe/thirdparty/providers/bitbucket.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// @ts-nocheck
import { TypeProvider } from "../types";
declare type TypeThirdPartyProviderBitbucketConfig = {
clientId: string;
clientSecret: string;
scope?: string[];
authorisationRedirect?: {
params?: {
[key: string]: string | ((request: any) => string);
};
};
isDefault?: boolean;
};
export default function Bitbucket(config: TypeThirdPartyProviderBitbucketConfig): TypeProvider;
export {};
147 changes: 147 additions & 0 deletions lib/build/recipe/thirdparty/providers/bitbucket.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
"use strict";
/* Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved.
*
* This software is licensed under the Apache License, Version 2.0 (the
* "License") as published by the Apache Software Foundation.
*
* You may not use this file except in compliance with 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.
*/
var __awaiter =
(this && this.__awaiter) ||
function (thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P
? value
: new P(function (resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault =
(this && this.__importDefault) ||
function (mod) {
return mod && mod.__esModule ? mod : { default: mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const axios_1 = __importDefault(require("axios"));
function Bitbucket(config) {
const id = "bitbucket";
function get(redirectURI, authCodeFromRequest) {
let accessTokenAPIURL = "https://bitbucket.org/site/oauth2/access_token";
let accessTokenAPIParams = {
client_id: config.clientId,
client_secret: config.clientSecret,
grant_type: "authorization_code",
};
if (authCodeFromRequest !== undefined) {
accessTokenAPIParams.code = authCodeFromRequest;
}
if (redirectURI !== undefined) {
accessTokenAPIParams.redirect_uri = redirectURI;
}
let authorisationRedirectURL = "https://bitbucket.org/site/oauth2/authorize";
let scopes = ["account", "email"];
if (config.scope !== undefined) {
scopes = config.scope;
scopes = Array.from(new Set(scopes));
}
let additionalParams =
config.authorisationRedirect === undefined || config.authorisationRedirect.params === undefined
? {}
: config.authorisationRedirect.params;
let authorizationRedirectParams = Object.assign(
{ scope: scopes.join(" "), access_type: "offline", response_type: "code", client_id: config.clientId },
additionalParams
);
function getProfileInfo(accessTokenAPIResponse) {
return __awaiter(this, void 0, void 0, function* () {
let accessToken = accessTokenAPIResponse.access_token;
let authHeader = `Bearer ${accessToken}`;
let response = yield axios_1.default({
method: "get",
url: "https://api.bitbucket.org/2.0/user",
headers: {
Authorization: authHeader,
},
});
let userInfo = response.data;
let id = userInfo.uuid;
let emailRes = yield axios_1.default({
method: "get",
url: "https://api.bitbucket.org/2.0/user/emails",
headers: {
Authorization: authHeader,
},
});
let emailData = emailRes.data;
let email = undefined;
let isVerified = false;
emailData.values.forEach((emailInfo) => {
if (emailInfo.is_primary) {
email = emailInfo.email;
isVerified = emailInfo.is_confirmed;
}
});
if (email === undefined) {
return {
id,
};
}
return {
id,
email: {
id: email,
isVerified,
},
};
});
}
return {
accessTokenAPI: {
url: accessTokenAPIURL,
params: accessTokenAPIParams,
},
authorisationRedirect: {
url: authorisationRedirectURL,
params: authorizationRedirectParams,
},
getProfileInfo,
getClientId: () => {
return config.clientId;
},
};
}
return {
id,
get,
isDefault: config.isDefault,
};
}
exports.default = Bitbucket;
16 changes: 16 additions & 0 deletions lib/build/recipe/thirdparty/providers/gitlab.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// @ts-nocheck
import { TypeProvider } from "../types";
declare type TypeThirdPartyProviderGitLabConfig = {
clientId: string;
clientSecret: string;
scope?: string[];
authorisationRedirect?: {
params?: {
[key: string]: string | ((request: any) => string);
};
};
gitlabBaseUrl?: string;
isDefault?: boolean;
};
export default function GitLab(config: TypeThirdPartyProviderGitLabConfig): TypeProvider;
export {};
138 changes: 138 additions & 0 deletions lib/build/recipe/thirdparty/providers/gitlab.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
"use strict";
/* Copyright (c) 2023, VRAI Labs and/or its affiliates. All rights reserved.
*
* This software is licensed under the Apache License, Version 2.0 (the
* "License") as published by the Apache Software Foundation.
*
* You may not use this file except in compliance with 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.
*/
var __awaiter =
(this && this.__awaiter) ||
function (thisArg, _arguments, P, generator) {
function adopt(value) {
return value instanceof P
? value
: new P(function (resolve) {
resolve(value);
});
}
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) {
try {
step(generator.next(value));
} catch (e) {
reject(e);
}
}
function rejected(value) {
try {
step(generator["throw"](value));
} catch (e) {
reject(e);
}
}
function step(result) {
result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected);
}
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault =
(this && this.__importDefault) ||
function (mod) {
return mod && mod.__esModule ? mod : { default: mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const axios_1 = __importDefault(require("axios"));
const normalisedURLDomain_1 = __importDefault(require("../../../normalisedURLDomain"));
function GitLab(config) {
const id = "gitlab";
function get(redirectURI, authCodeFromRequest) {
let baseUrl =
config.gitlabBaseUrl === undefined
? "https://gitlab.com" // no traling slash cause we add that in the path
: new normalisedURLDomain_1.default(config.gitlabBaseUrl).getAsStringDangerous();
let accessTokenAPIURL = baseUrl + "/oauth/token";
let accessTokenAPIParams = {
client_id: config.clientId,
client_secret: config.clientSecret,
grant_type: "authorization_code",
};
if (authCodeFromRequest !== undefined) {
accessTokenAPIParams.code = authCodeFromRequest;
}
if (redirectURI !== undefined) {
accessTokenAPIParams.redirect_uri = redirectURI;
}
let authorisationRedirectURL = baseUrl + "/oauth/authorize";
let scopes = ["read_user"];
if (config.scope !== undefined) {
scopes = config.scope;
scopes = Array.from(new Set(scopes));
}
let additionalParams =
config.authorisationRedirect === undefined || config.authorisationRedirect.params === undefined
? {}
: config.authorisationRedirect.params;
let authorizationRedirectParams = Object.assign(
{ scope: scopes.join(" "), response_type: "code", client_id: config.clientId },
additionalParams
);
function getProfileInfo(accessTokenAPIResponse) {
return __awaiter(this, void 0, void 0, function* () {
let accessToken = accessTokenAPIResponse.access_token;
let authHeader = `Bearer ${accessToken}`;
let response = yield axios_1.default({
method: "get",
url: baseUrl + "/api/v4/user",
headers: {
Authorization: authHeader,
},
});
let userInfo = response.data;
let id = userInfo.id + "";
let email = userInfo.email;
if (email === undefined || email === null) {
return {
id,
};
}
let isVerified = userInfo.confirmed_at !== null && userInfo.confirmed_at !== undefined;
return {
id,
email: {
id: email,
isVerified,
},
};
});
}
return {
accessTokenAPI: {
url: accessTokenAPIURL,
params: accessTokenAPIParams,
},
authorisationRedirect: {
url: authorisationRedirectURL,
params: authorizationRedirectParams,
},
getProfileInfo,
getClientId: () => {
return config.clientId;
},
};
}
return {
id,
get,
isDefault: config.isDefault,
};
}
exports.default = GitLab;
4 changes: 4 additions & 0 deletions lib/build/recipe/thirdparty/providers/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,13 @@ import ProviderGithub from "./github";
import ProviderApple from "./apple";
import ProviderDiscord from "./discord";
import ProviderGoogleWorkspaces from "./googleWorkspaces";
import ProviderBitbucket from "./bitbucket";
import ProviderGitlab from "./gitlab";
export declare let Google: typeof ProviderGoogle;
export declare let Facebook: typeof ProviderFacebook;
export declare let Github: typeof ProviderGithub;
export declare let Apple: typeof ProviderApple;
export declare let Discord: typeof ProviderDiscord;
export declare let GoogleWorkspaces: typeof ProviderGoogleWorkspaces;
export declare let Bitbucket: typeof ProviderBitbucket;
export declare let GitLab: typeof ProviderGitlab;
Loading