Skip to content

Commit

Permalink
feat: add sdk for web front-only app
Browse files Browse the repository at this point in the history
  • Loading branch information
leo220yuyaodog committed Sep 8, 2023
1 parent 3ac4ed3 commit 785ae3a
Show file tree
Hide file tree
Showing 3 changed files with 1,491 additions and 87 deletions.
11 changes: 7 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@
"@semantic-release/npm": "^7.1.3",
"@semantic-release/release-notes-generator": "^9.0.3",
"@types/jest": "^27.0.2",
"jest": "^27.2.1",
"npm-run-all": "^4.1.5",
"typescript": "^4.5.5",
"rimraf": "^3.0.2",
"jest": "^27.2.1",
"semantic-release": "19.0.3",
"ts-jest": "^27.0.5",
"semantic-release": "^17.4.4"
"typescript": "^4.5.5"
},
"files": [
"lib"
Expand All @@ -74,5 +74,8 @@
"bugs": {
"url": "https://github.com/casdoor/casdoor-js-sdk/issues"
},
"homepage": "https://github.com/casdoor/casdoor-js-sdk"
"homepage": "https://github.com/casdoor/casdoor-js-sdk",
"dependencies": {
"js-pkce": "^1.3.0"
}
}
57 changes: 46 additions & 11 deletions src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.

import PKCE from 'js-pkce';
import ITokenResponse from "js-pkce/dist/ITokenResponse";

export interface SdkConfig {
serverUrl: string, // your Casdoor server URL, e.g., "https://door.casbin.com" for the official demo site
clientId: string, // the Client ID of your Casdoor application, e.g., "014ae4bd048734ca2dea"
appName: string, // the name of your Casdoor application, e.g., "app-casnode"
organizationName: string // the name of the Casdoor organization connected with your Casdoor application, e.g., "casbin"
redirectPath?: string // the path of the redirect URL for your Casdoor application, will be "/callback" if not provided
signinPath?: string // the path of the signin URL for your Casdoor applcation, will be "/api/signin" if not provided
scope?: string // apply for permission to obtain the user information, will be "profile" if not provided
}

// reference: https://github.com/casdoor/casdoor-go-sdk/blob/90fcd5646ec63d733472c5e7ce526f3447f99f1f/auth/jwt.go#L19-L32
Expand All @@ -40,21 +44,25 @@ export interface Account {

class Sdk {
private config: SdkConfig
private pkce : PKCE

constructor(config: SdkConfig) {
this.config = config
if (config.redirectPath === undefined || config.redirectPath === null) {
this.config.redirectPath = "/callback";
}
}

public getSignupUrl(enablePassword: boolean = true): string {
if (enablePassword) {
sessionStorage.setItem("signinUrl", this.getSigninUrl());
return `${this.config.serverUrl.trim()}/signup/${this.config.appName}`;
} else {
return this.getSigninUrl().replace("/login/oauth/authorize", "/signup/oauth/authorize");
if(config.scope === undefined || config.scope === null) {
this.config.scope = "profile";
}

this.pkce = new PKCE({
client_id: this.config.clientId,
redirect_uri: `${window.location.origin}${this.config.redirectPath}`,
authorization_endpoint: `${this.config.serverUrl.trim()}/login/oauth/authorize`,
token_endpoint: `${this.config.serverUrl.trim()}/api/login/oauth/access_token`,
requested_scopes: this.config.scope || "profile",
});
}

getOrSaveState(): string {
Expand All @@ -72,11 +80,19 @@ class Sdk {
sessionStorage.removeItem("casdoor-state");
}

public getSignupUrl(enablePassword: boolean = true): string {
if (enablePassword) {
sessionStorage.setItem("signinUrl", this.getSigninUrl());
return `${this.config.serverUrl.trim()}/signup/${this.config.appName}`;
} else {
return this.getSigninUrl().replace("/login/oauth/authorize", "/signup/oauth/authorize");

Check warning on line 88 in src/sdk.ts

View check run for this annotation

Codecov / codecov/patch

src/sdk.ts#L85-L88

Added lines #L85 - L88 were not covered by tests
}
}

public getSigninUrl(): string {
const redirectUri = this.config.redirectPath && this.config.redirectPath.includes('://') ? this.config.redirectPath : `${window.location.origin}${this.config.redirectPath}`;
const scope = "read";
const state = this.getOrSaveState();
return `${this.config.serverUrl.trim()}/login/oauth/authorize?client_id=${this.config.clientId}&response_type=code&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${scope}&state=${state}`;
return `${this.config.serverUrl.trim()}/login/oauth/authorize?client_id=${this.config.clientId}&response_type=code&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${this.config.scope}&state=${state}`;
}

public getUserProfileUrl(userName: string, account: Account): string {
Expand Down Expand Up @@ -135,12 +151,12 @@ class Sdk {
const iframe = document.createElement('iframe');
iframe.style.display = 'none';
iframe.src = `${this.getSigninUrl()}&silentSignin=1`;

const handleMessage = (event: MessageEvent) => {
if (window !== window.parent) {
return null;
}

const message = event.data;
if (message.tag !== "Casdoor" || message.type !== "SilentSignin") {
return;
Expand Down Expand Up @@ -183,6 +199,25 @@ class Sdk {

window.addEventListener("message", handleMessage);
}

public async signin_redirect(): Promise<void> {
window.location.href = this.pkce.authorizeUrl();

Check warning on line 204 in src/sdk.ts

View check run for this annotation

Codecov / codecov/patch

src/sdk.ts#L203-L204

Added lines #L203 - L204 were not covered by tests
}

public async exchangeForAccessToken(): Promise<ITokenResponse> {
return this.pkce.exchangeForAccessToken(window.location.href)

Check warning on line 208 in src/sdk.ts

View check run for this annotation

Codecov / codecov/patch

src/sdk.ts#L207-L208

Added lines #L207 - L208 were not covered by tests
}

public async getUserInfo(accessToken: string): Promise<Response> {
return fetch(`${this.config.serverUrl.trim()}/api/userinfo`, {

Check warning on line 212 in src/sdk.ts

View check run for this annotation

Codecov / codecov/patch

src/sdk.ts#L211-L212

Added lines #L211 - L212 were not covered by tests
method: "GET",
headers: {
"Authorization": `Bearer ${accessToken}`,
"Content-Type": "application/json"
},
}).then(res => res.json()

Check warning on line 218 in src/sdk.ts

View check run for this annotation

Codecov / codecov/patch

src/sdk.ts#L218

Added line #L218 was not covered by tests
);
}
}

export default Sdk;
Loading

0 comments on commit 785ae3a

Please sign in to comment.