From bb39be24e308f5feeadf53115f860753e517e58b Mon Sep 17 00:00:00 2001 From: Kimmy Taft Date: Wed, 11 Dec 2019 16:17:14 -0600 Subject: [PATCH 01/20] add instructions on securing an app from scratch --- react-sample-app/README.md | 139 +++++++++++++++++++++++++++++++++++-- 1 file changed, 132 insertions(+), 7 deletions(-) diff --git a/react-sample-app/README.md b/react-sample-app/README.md index 0d2adea..ebec78d 100644 --- a/react-sample-app/README.md +++ b/react-sample-app/README.md @@ -1,6 +1,6 @@ # IBM Cloud AppID React Sample App -The IBM Cloud AppID SDK can be used with React to create a secure single-page application. You will need an IBM Cloud App ID instance with a single-page application created. Use the clientId and discoveryEndpoint from the application credentials to initialize the AppID instance. +The IBM Cloud App ID SDK can be used with React to create a secure single-page application. You will need an IBM Cloud App ID instance with a single-page application created. Use the client ID and discovery endpoint from your application credentials to initialize the App ID instance. ## Prerequisites * Node.js version 8 or later @@ -10,22 +10,147 @@ The IBM Cloud AppID SDK can be used with React to create a secure single-page ap ## To run locally -* Clone the repository +1. Clone the repository. ``` -git clone https://github.ibm.com/Bernhardt-Ramat/react-sample +git clone https://github.com/ibm-cloud-security/appid-sample-code-snippets.git ``` -* Navigate to application workspace folder. +2. Navigate to application workspace folder. ``` -cd react-sample +cd react-sample-app ``` -* To get the dpendencies for the app installed run +3. Install dependencies for the application. ``` npm install ``` -* To start the development server run +4. Start the development server. Navigate to http://localhost:3000 to access your application. ``` npm start ``` The app will automatically reload if you change any of the source files. + +## Detailed instructions on creating and securing an app from scratch + +### Creating your app + +1. Set up a frontend build pipelines by using Create React App. +```JSX +npx create-react-app my-app +cd my-app +``` +2. Install the IBM Cloud AppID SDK. +```JSX +npm install ibmcloud-appid-js +``` +3. In your code editor, in the `src` directory of the application, open the `App.js` file. Import App ID by adding the following code: +```JSX +import AppID from 'ibmcloud-appid-js'; +``` +4. In the main App() function, declare a new App ID instance with `useMemo`, which recomputes a memoized value when a dependency changes. +```JSX +const appid = useMemo(() => { + return new AppID() + }, []); +``` +5. Initialize App ID and add error handling. Add your client ID and discovery endpoint which can be found in the Applications tab of the App ID dashboard. +```JSX +const [errorState, setErrorState] = React.useState(false); +const [errorMessage, setErrorMessage] = React.useState(''); +(async () => { + try { + await appid.init({ + clientId: '', + discoveryEndpoint: '' + }); + } catch (e) { + setErrorState(true); + setErrorMessage(e.message); + } + })(); +``` +6. Create a login action that will execute when the login button is clicked. After a successful authentication, the welcomeDisplayState will be set to true and the userName will be set to the name returned in the App ID token. +```JSX +const [welcomeDisplayState, setWelcomeDisplayState] = React.useState(false); +const [loginButtonDisplayState, setLoginButtonDisplayState] = React.useState(true); +const [userName, setUserName] = React.useState(''); +const loginAction = async () => { + try { + const tokens = await appID.signin(); + setErrorState(false); + setLoginButtonDisplayState(false); + setWelcomeDisplayState(true); + setUserName(tokens.idTokenPayload.name); + } catch (e) { + setErrorState(true); + setErrorMessage(e.message); + } +}; +``` +7. Add a welcome div, the login button that calls the login action, and an error div. +```JSX +{welcomeDisplayState &&
Welcome {userName}! You are now authenticated.
} +{loginButtonDisplayState && } +{errorState &&
{errorMessage}
} +``` +8. Save all of the files. Your entire `App.js` file should look like this: +```JSX +import React from 'react'; +import logo from './logo.svg'; +import './App.css'; +import AppID from 'ibmcloud-appid-js'; + +function App() { + const appID = React.useMemo(() => { + return new AppID() +}, []); + +const [errorState, setErrorState] = React.useState(false); +const [errorMessage, setErrorMessage] = React.useState(''); +(async () => { + try { + await appID.init({ + 'clientId': '', + 'discoveryEndpoint': '' + }); + } catch (e) { + setErrorState(true); + setErrorMessage(e.message); + } +})(); + +const [welcomeDisplayState, setWelcomeDisplayState] = React.useState(false); +const [loginButtonDisplayState, setLoginButtonDisplayState] = React.useState(true); +const [userName, setUserName] = React.useState(''); +const loginAction = async () => { + try { + const tokens = await appID.signin(); + setErrorState(false); + setLoginButtonDisplayState(false); + setWelcomeDisplayState(true); + setUserName(tokens.idTokenPayload.name); + } catch (e) { + setErrorState(true); + setErrorMessage(e.message); + } +}; + return ( +
+
+ logo + {welcomeDisplayState &&
Welcome {userName}! You are now authenticated.
} + {loginButtonDisplayState && } + {errorState &&
{errorMessage}
} +
+
+ ); +} + +export default App; +``` +9. Open your terminal. Run the following command to access your app from http://localhost:3000. +```JSX +npm start +``` + +Well done! You successfully integrated IBM Cloud App ID's SDK for SPA into a React application. From 2e14766c83c85a6a7608ad5ec6d1de5a2bf58378 Mon Sep 17 00:00:00 2001 From: Kimmy Taft Date: Thu, 12 Dec 2019 14:22:48 -0600 Subject: [PATCH 02/20] add cursor --- react-sample-app/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react-sample-app/README.md b/react-sample-app/README.md index ebec78d..3e912fe 100644 --- a/react-sample-app/README.md +++ b/react-sample-app/README.md @@ -139,7 +139,7 @@ const loginAction = async () => {
logo {welcomeDisplayState &&
Welcome {userName}! You are now authenticated.
} - {loginButtonDisplayState && } + {loginButtonDisplayState && } {errorState &&
{errorMessage}
}
From 8859a98c44cc6510cb66b9698a043b9ba2dad214 Mon Sep 17 00:00:00 2001 From: Kimmy Taft Date: Thu, 12 Dec 2019 14:31:15 -0600 Subject: [PATCH 03/20] add cursor --- react-sample-app/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/react-sample-app/README.md b/react-sample-app/README.md index 3e912fe..896f2f7 100644 --- a/react-sample-app/README.md +++ b/react-sample-app/README.md @@ -90,7 +90,7 @@ const loginAction = async () => { 7. Add a welcome div, the login button that calls the login action, and an error div. ```JSX {welcomeDisplayState &&
Welcome {userName}! You are now authenticated.
} -{loginButtonDisplayState && } +{loginButtonDisplayState && } {errorState &&
{errorMessage}
} ``` 8. Save all of the files. Your entire `App.js` file should look like this: From 06dd96898b08f93add225bef3bcfc436ceb57d36 Mon Sep 17 00:00:00 2001 From: Bernie Date: Thu, 12 Dec 2019 14:32:51 -0700 Subject: [PATCH 04/20] Pushing the React spa app to the repo --- react-sample-app/.gitignore | 1 + react-sample-app/README.md | 125 -------------------- react-sample-app/package-lock.json | 86 ++++++++------ react-sample-app/package.json | 2 +- react-sample-app/public/robots.txt | 2 + react-sample-app/src/App.css | 38 ++++++ react-sample-app/src/App.js | 61 +++++++++- react-sample-app/src/Welcome.js | 91 -------------- react-sample-app/src/images/20@2x.svg | 11 -- react-sample-app/src/images/app_id_icon.svg | 11 -- react-sample-app/src/images/hint_icon.svg | 42 ------- react-sample-app/src/index.css | 121 ++----------------- 12 files changed, 161 insertions(+), 430 deletions(-) create mode 100644 react-sample-app/public/robots.txt delete mode 100644 react-sample-app/src/Welcome.js delete mode 100644 react-sample-app/src/images/20@2x.svg delete mode 100644 react-sample-app/src/images/app_id_icon.svg delete mode 100644 react-sample-app/src/images/hint_icon.svg diff --git a/react-sample-app/.gitignore b/react-sample-app/.gitignore index e81b288..c7cd241 100644 --- a/react-sample-app/.gitignore +++ b/react-sample-app/.gitignore @@ -5,6 +5,7 @@ /.pnp .pnp.js .idea + # testing /coverage diff --git a/react-sample-app/README.md b/react-sample-app/README.md index 896f2f7..0538469 100644 --- a/react-sample-app/README.md +++ b/react-sample-app/README.md @@ -29,128 +29,3 @@ npm start ``` The app will automatically reload if you change any of the source files. - -## Detailed instructions on creating and securing an app from scratch - -### Creating your app - -1. Set up a frontend build pipelines by using Create React App. -```JSX -npx create-react-app my-app -cd my-app -``` -2. Install the IBM Cloud AppID SDK. -```JSX -npm install ibmcloud-appid-js -``` -3. In your code editor, in the `src` directory of the application, open the `App.js` file. Import App ID by adding the following code: -```JSX -import AppID from 'ibmcloud-appid-js'; -``` -4. In the main App() function, declare a new App ID instance with `useMemo`, which recomputes a memoized value when a dependency changes. -```JSX -const appid = useMemo(() => { - return new AppID() - }, []); -``` -5. Initialize App ID and add error handling. Add your client ID and discovery endpoint which can be found in the Applications tab of the App ID dashboard. -```JSX -const [errorState, setErrorState] = React.useState(false); -const [errorMessage, setErrorMessage] = React.useState(''); -(async () => { - try { - await appid.init({ - clientId: '', - discoveryEndpoint: '' - }); - } catch (e) { - setErrorState(true); - setErrorMessage(e.message); - } - })(); -``` -6. Create a login action that will execute when the login button is clicked. After a successful authentication, the welcomeDisplayState will be set to true and the userName will be set to the name returned in the App ID token. -```JSX -const [welcomeDisplayState, setWelcomeDisplayState] = React.useState(false); -const [loginButtonDisplayState, setLoginButtonDisplayState] = React.useState(true); -const [userName, setUserName] = React.useState(''); -const loginAction = async () => { - try { - const tokens = await appID.signin(); - setErrorState(false); - setLoginButtonDisplayState(false); - setWelcomeDisplayState(true); - setUserName(tokens.idTokenPayload.name); - } catch (e) { - setErrorState(true); - setErrorMessage(e.message); - } -}; -``` -7. Add a welcome div, the login button that calls the login action, and an error div. -```JSX -{welcomeDisplayState &&
Welcome {userName}! You are now authenticated.
} -{loginButtonDisplayState && } -{errorState &&
{errorMessage}
} -``` -8. Save all of the files. Your entire `App.js` file should look like this: -```JSX -import React from 'react'; -import logo from './logo.svg'; -import './App.css'; -import AppID from 'ibmcloud-appid-js'; - -function App() { - const appID = React.useMemo(() => { - return new AppID() -}, []); - -const [errorState, setErrorState] = React.useState(false); -const [errorMessage, setErrorMessage] = React.useState(''); -(async () => { - try { - await appID.init({ - 'clientId': '', - 'discoveryEndpoint': '' - }); - } catch (e) { - setErrorState(true); - setErrorMessage(e.message); - } -})(); - -const [welcomeDisplayState, setWelcomeDisplayState] = React.useState(false); -const [loginButtonDisplayState, setLoginButtonDisplayState] = React.useState(true); -const [userName, setUserName] = React.useState(''); -const loginAction = async () => { - try { - const tokens = await appID.signin(); - setErrorState(false); - setLoginButtonDisplayState(false); - setWelcomeDisplayState(true); - setUserName(tokens.idTokenPayload.name); - } catch (e) { - setErrorState(true); - setErrorMessage(e.message); - } -}; - return ( -
-
- logo - {welcomeDisplayState &&
Welcome {userName}! You are now authenticated.
} - {loginButtonDisplayState && } - {errorState &&
{errorMessage}
} -
-
- ); -} - -export default App; -``` -9. Open your terminal. Run the following command to access your app from http://localhost:3000. -```JSX -npm start -``` - -Well done! You successfully integrated IBM Cloud App ID's SDK for SPA into a React application. diff --git a/react-sample-app/package-lock.json b/react-sample-app/package-lock.json index 92fa0ad..318d3f7 100644 --- a/react-sample-app/package-lock.json +++ b/react-sample-app/package-lock.json @@ -1383,9 +1383,9 @@ } }, "@testing-library/react": { - "version": "9.3.2", - "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/@testing-library/react/-/react-9.3.2.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Freact%2F-%2Freact-9.3.2.tgz", - "integrity": "sha1-QYAA2qmA2v0tlCDMcz1mHa7OmqA=", + "version": "9.3.3", + "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/@testing-library/react/-/react-9.3.3.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2F%40testing-library%2Freact%2F-%2Freact-9.3.3.tgz", + "integrity": "sha1-h/5ZStsCy6TQ6GNp0CXqE61XDXw=", "requires": { "@babel/runtime": "^7.6.0", "@testing-library/dom": "^6.3.0", @@ -1410,9 +1410,9 @@ } }, "@types/babel__generator": { - "version": "7.6.0", - "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/@types/babel__generator/-/babel__generator-7.6.0.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2F%40types%2Fbabel__generator%2F-%2Fbabel__generator-7.6.0.tgz", - "integrity": "sha1-8ewcEE0btGNVbstyQBireI0MFyo=", + "version": "7.6.1", + "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/@types/babel__generator/-/babel__generator-7.6.1.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2F%40types%2Fbabel__generator%2F-%2Fbabel__generator-7.6.1.tgz", + "integrity": "sha1-SQF2ezl+hxGuuZ3405bXunt/DgQ=", "requires": { "@babel/types": "^7.0.0" } @@ -1487,9 +1487,9 @@ "integrity": "sha1-PcoOPzOyAPx9ETnAzZbBJoyt/Z0=" }, "@types/node": { - "version": "12.12.16", - "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/@types/node/-/node-12.12.16.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2F%40types%2Fnode%2F-%2Fnode-12.12.16.tgz", - "integrity": "sha1-Pry9e/l4+kxRIP7ovlcIMnGos6w=" + "version": "12.12.17", + "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/@types/node/-/node-12.12.17.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2F%40types%2Fnode%2F-%2Fnode-12.12.17.tgz", + "integrity": "sha1-GRtx5/TDJe4PsjvEqZZHfZK4w5s=" }, "@types/parse-json": { "version": "4.0.0", @@ -1970,12 +1970,32 @@ "integrity": "sha1-JO+AoowaiTYX4hSbDG0NeIKTsJk=" }, "array-includes": { - "version": "3.0.3", - "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/array-includes/-/array-includes-3.0.3.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2Farray-includes%2F-%2Farray-includes-3.0.3.tgz", - "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "version": "3.1.0", + "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/array-includes/-/array-includes-3.1.0.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2Farray-includes%2F-%2Farray-includes-3.1.0.tgz", + "integrity": "sha1-SKkp70xrsfptxKksmwI6JhsMpAQ=", "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.7.0" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.0" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.0-next.1", + "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/es-abstract/-/es-abstract-1.17.0-next.1.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2Fes-abstract%2F-%2Fes-abstract-1.17.0-next.1.tgz", + "integrity": "sha1-lKzJPiCwWm6W2stasvHLOoH8IXI=", + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" + } + } } }, "array-union": { @@ -3825,23 +3845,23 @@ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" }, "core-js": { - "version": "3.4.8", - "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/core-js/-/core-js-3.4.8.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2Fcore-js%2F-%2Fcore-js-3.4.8.tgz", - "integrity": "sha1-4PwMYfLvkMvBDFMdv/qkbftxUt0=" + "version": "3.5.0", + "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/core-js/-/core-js-3.5.0.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2Fcore-js%2F-%2Fcore-js-3.5.0.tgz", + "integrity": "sha1-Zt+OSb5L13Xm+VKp0IO3Vq1Bwe0=" }, "core-js-compat": { - "version": "3.4.8", - "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/core-js-compat/-/core-js-compat-3.4.8.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2Fcore-js-compat%2F-%2Fcore-js-compat-3.4.8.tgz", - "integrity": "sha1-9y5qTtdkN+pxCSj0RhX5JqgWB9U=", + "version": "3.5.0", + "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/core-js-compat/-/core-js-compat-3.5.0.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2Fcore-js-compat%2F-%2Fcore-js-compat-3.5.0.tgz", + "integrity": "sha1-WhGmGanp3S3PHHQrIGC8SiFD5bY=", "requires": { "browserslist": "^4.8.2", "semver": "^6.3.0" } }, "core-js-pure": { - "version": "3.4.8", - "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/core-js-pure/-/core-js-pure-3.4.8.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2Fcore-js-pure%2F-%2Fcore-js-pure-3.4.8.tgz", - "integrity": "sha1-pEFYNDg3hOgZdM00Mh2vNqbSNm4=" + "version": "3.5.0", + "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/core-js-pure/-/core-js-pure-3.5.0.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2Fcore-js-pure%2F-%2Fcore-js-pure-3.5.0.tgz", + "integrity": "sha1-9jx/KyRefWeOc/h60oUFSAVU1w4=" }, "core-util-is": { "version": "1.0.2", @@ -12290,9 +12310,9 @@ } }, "stream-shift": { - "version": "1.0.0", - "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/stream-shift/-/stream-shift-1.0.0.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2Fstream-shift%2F-%2Fstream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" + "version": "1.0.1", + "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/stream-shift/-/stream-shift-1.0.1.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2Fstream-shift%2F-%2Fstream-shift-1.0.1.tgz", + "integrity": "sha1-1wiCgVWasneEJCebCHfaPDktWj0=" }, "strict-uri-encode": { "version": "1.1.0", @@ -12573,9 +12593,9 @@ }, "dependencies": { "find-cache-dir": { - "version": "3.1.0", - "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/find-cache-dir/-/find-cache-dir-3.1.0.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2Ffind-cache-dir%2F-%2Ffind-cache-dir-3.1.0.tgz", - "integrity": "sha1-mTWJSZnevvTPn2d/32RtACxM3ss=", + "version": "3.2.0", + "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/find-cache-dir/-/find-cache-dir-3.2.0.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2Ffind-cache-dir%2F-%2Ffind-cache-dir-3.2.0.tgz", + "integrity": "sha1-5/5EwavBKZ9RYUblYxCP0QBsGHQ=", "requires": { "commondir": "^1.0.1", "make-dir": "^3.0.0", @@ -13276,15 +13296,15 @@ } }, "terser-webpack-plugin": { - "version": "1.4.2", - "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/terser-webpack-plugin/-/terser-webpack-plugin-1.4.2.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2Fterser-webpack-plugin%2F-%2Fterser-webpack-plugin-1.4.2.tgz", - "integrity": "sha1-4jwNVUWH0fRzvQz2hidyDnM4kKQ=", + "version": "1.4.3", + "resolved": "https://na.artifactory.swg-devops.com:443/artifactory/api/npm/wcp-sec-srv-npm-virtual/terser-webpack-plugin/-/terser-webpack-plugin-1.4.3.tgz?dl=https%3A%2F%2Fregistry.npmjs.org%2Fterser-webpack-plugin%2F-%2Fterser-webpack-plugin-1.4.3.tgz", + "integrity": "sha1-Xsry29xfuZdF/QZ5H0b8ndscmnw=", "requires": { "cacache": "^12.0.2", "find-cache-dir": "^2.1.0", "is-wsl": "^1.1.0", "schema-utils": "^1.0.0", - "serialize-javascript": "^2.1.1", + "serialize-javascript": "^2.1.2", "source-map": "^0.6.1", "terser": "^4.1.2", "webpack-sources": "^1.4.0", diff --git a/react-sample-app/package.json b/react-sample-app/package.json index 0f4a77e..c74da1e 100644 --- a/react-sample-app/package.json +++ b/react-sample-app/package.json @@ -4,7 +4,7 @@ "private": true, "dependencies": { "@testing-library/jest-dom": "^4.2.4", - "@testing-library/react": "^9.3.2", + "@testing-library/react": "^9.3.3", "@testing-library/user-event": "^7.1.2", "ibmcloud-appid-js": "^0.3.1", "react": "^16.12.0", diff --git a/react-sample-app/public/robots.txt b/react-sample-app/public/robots.txt new file mode 100644 index 0000000..01b0f9a --- /dev/null +++ b/react-sample-app/public/robots.txt @@ -0,0 +1,2 @@ +# https://www.robotstxt.org/robotstxt.html +User-agent: * diff --git a/react-sample-app/src/App.css b/react-sample-app/src/App.css index e69de29..74b5e05 100644 --- a/react-sample-app/src/App.css +++ b/react-sample-app/src/App.css @@ -0,0 +1,38 @@ +.App { + text-align: center; +} + +.App-logo { + height: 40vmin; + pointer-events: none; +} + +@media (prefers-reduced-motion: no-preference) { + .App-logo { + animation: App-logo-spin infinite 20s linear; + } +} + +.App-header { + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; +} + +.App-link { + color: #61dafb; +} + +@keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/react-sample-app/src/App.js b/react-sample-app/src/App.js index 302a449..a8f0f05 100644 --- a/react-sample-app/src/App.js +++ b/react-sample-app/src/App.js @@ -1,11 +1,62 @@ import React from 'react'; -import Welcome from './Welcome' +import logo from './logo.svg'; +import './App.css'; +import AppID from 'ibmcloud-appid-js'; + +function App() { + + const appID = React.useMemo(() => { + return new AppID() + }, []); + + const [errorState, setErrorState] = React.useState(false); + const [errorMessage, setErrorMessage] = React.useState(''); + + (async () => { + try { + await appID.init({ + clientId: '', + discoveryEndpoint: '' + }); + } catch (e) { + setErrorState(true); + setErrorMessage(e.message); + } + })(); + + const [welcomeDisplayState, setWelcomeDisplayState] = React.useState(false); + const [loginButtonDisplayState, setLoginButtonDisplayState] = React.useState(true); + const [userName, setUserName] = React.useState(''); + + const loginAction = async () => { + try { + const tokens = await appID.signin(); + setErrorState(false); + setLoginButtonDisplayState(false); + setWelcomeDisplayState(true); + setUserName(tokens.idTokenPayload.name); + } catch (e) { + setErrorState(true); + setErrorMessage(e.message); + } + }; -export default function App() { return ( - <> - - +
+
+ logo + {welcomeDisplayState &&
Welcome {userName}! You are now authenticated.
} + {loginButtonDisplayState && + + } + {errorState &&
{errorMessage}
} +
+
); } +export default App; diff --git a/react-sample-app/src/Welcome.js b/react-sample-app/src/Welcome.js deleted file mode 100644 index 84c62ae..0000000 --- a/react-sample-app/src/Welcome.js +++ /dev/null @@ -1,91 +0,0 @@ -import React, {useMemo, useState} from 'react'; -import logo from './images/app_id_icon.svg'; -import hint from './images/hint_icon.svg'; -import AppID from 'ibmcloud-appid-js'; - -export default function Welcome() { - const [userName, setUserName] = useState(''); - const [idToken, setIdToken] = useState(''); - const [userInfo, setUserInfo] = useState(''); - const [errorState, setErrorState] = useState('hide') - const [errorMessage, setErrorMessage] = useState('Error'); - const [displayState, setDisplayState] = useState('show'); - const [welcomeDisplayState, setWelcomeDisplayState] = useState('hide'); - - const appid = useMemo(() => { - return new AppID() - }, []); - - (async () => { - try { - await appid.init({ - "clientId": "", - "discoveryEndpoint": "" - }); - } catch (e) { - setErrorState('error') - setErrorMessage(e.message); - } - })(); - - const loginAction = async () => { - try { - const tokens = await appid.signin(); - const userInformation = await appid.getUserInfo(tokens.accessToken); - const decodeToken = tokens.idTokenPayload; - setUserName(decodeToken.name); - setIdToken(JSON.stringify(decodeToken)); - setUserInfo(JSON.stringify(userInformation)); - setDisplayState('hide'); - setWelcomeDisplayState('show'); - } catch (e) { - setErrorState('error') - setErrorMessage(e.message); - } - }; - return ( - <> -
- IBM Cloud AppID SDK Sample SPA -
-
-
- App ID Logo -

- Welcome to the
- IBM Cloud App ID SPA SDK
- Sample App -

- -
{errorMessage}
-
-
-
- hint icon -
-
- Hint: To get started, click
- the Login button above to reveal
- the App ID login Pop-up window. -
-
-
-
-
-

Hi {userName}, Congratulations!

-

You've made your first authentication.

-
-
-

ID Token

-
-

{idToken}

-
-
-

User Information

-
-

{userInfo}

-
-
- - ); -} diff --git a/react-sample-app/src/images/20@2x.svg b/react-sample-app/src/images/20@2x.svg deleted file mode 100644 index 7978fd9..0000000 --- a/react-sample-app/src/images/20@2x.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - Actions / Navigation / chevron--down / 20@2x - Created with Sketch. - - - - - - \ No newline at end of file diff --git a/react-sample-app/src/images/app_id_icon.svg b/react-sample-app/src/images/app_id_icon.svg deleted file mode 100644 index 8519f05..0000000 --- a/react-sample-app/src/images/app_id_icon.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - diff --git a/react-sample-app/src/images/hint_icon.svg b/react-sample-app/src/images/hint_icon.svg deleted file mode 100644 index 14d8a45..0000000 --- a/react-sample-app/src/images/hint_icon.svg +++ /dev/null @@ -1,42 +0,0 @@ - - - - Group 5 Copy - Created with Sketch. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/react-sample-app/src/index.css b/react-sample-app/src/index.css index 1f15824..ec2585e 100644 --- a/react-sample-app/src/index.css +++ b/react-sample-app/src/index.css @@ -1,114 +1,13 @@ body { margin: 0; - padding: 0; - max-width: 100%; - overflow-x: hidden; -} -.wrapper { - display: flex; - justify-content: space-between; - background-color: #EBF0F7; - font-family: 'IBMPlexSans-SemiBold', sans-serif; - margin-bottom: 3%; - width: 100%; - height: 40px; - font-size: 14px; - color: #000000; - padding: 10px; - line-height: 40px; -} -@-moz-document url-prefix() { - .wrapper { - font-family: 'IBM Plex Sans SemiBold', 'Helvetica Neue', Arial, sans-serif; - } -} -.logo-icon { - display: block; - width: 70px; - height: 70px; - margin: 0 auto; - margin-bottom: 20px; -} -#login { - font-family: 'IBMPlexSans-Medium', sans-serif; - font-size: 14px; - color: #FFFFFF; - letter-spacing: 0; - text-align: center; - background-color: #4178BE; - border: none; - padding: 10px 40px; - text-decoration: none; - cursor: pointer; - width: 158px; - height: 40px; - margin: 0 auto; - margin-top: 20px; -} -@-moz-document url-prefix() { - #login { - font-family: 'IBM Plex Sans Medium', 'Helvetica Neue', Arial, sans-serif; - } -} -.welcome-display { - display: block; - margin: 0 auto; - width: 30%; - height: auto; - font-family: 'IBMPlexSans-Light', sans-serif; - font-size: 1.5vw; - color: #152935; - letter-spacing: 0; - text-align: center; -} -@-moz-document url-prefix() { - .welcome-display { - font-family: 'IBM Plex Sans Light', 'Helvetica Neue', Arial, sans-serif; - } -} -.hintSection { - display: flex; - justify-content: center; - margin-top: 5%; - margin-bottom: 10%; -} -.flex-bottom { - font-family: 'IBMPlexSans-Medium', sans-serif; - font-size: 14px; - color: #42535C; - letter-spacing: 0; - line-height: 20px; - font-weight: normal; - flex: none; - margin-right: 5px; - margin-left: 5px; -} -@-moz-document url-prefix() { - .flex-bottom { - font-family: 'IBM Plex Sans Medium', sans-serif; - } -} -.hide { - display: none; -} -.show { - display: block -} -.error { - padding-top: 20px; - font-size: 14px; - color: red; -} -.token-display, .info-display { - display: block; - width: 50%; - height: auto; - font-family: 'IBMPlexSans-Light', sans-serif; - font-size: 1vw; - color: #152935; - letter-spacing: 0; - word-break: break-all; - padding: 5px; - border-radius: 10px; - margin: 0 auto 15px; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; } From 7dee242703cf0bc7a46b7ed1bce90e4d3af3f22f Mon Sep 17 00:00:00 2001 From: Bernie Date: Fri, 13 Dec 2019 05:43:09 -0700 Subject: [PATCH 05/20] Pushing the Angular spa app to the repo --- angular-sample-spa/README.md | 14 ++--- angular-sample-spa/src/app/app.component.html | 56 ++++++------------- angular-sample-spa/src/app/app.component.ts | 30 +++++----- 3 files changed, 37 insertions(+), 63 deletions(-) diff --git a/angular-sample-spa/README.md b/angular-sample-spa/README.md index bbb7081..a78ceac 100644 --- a/angular-sample-spa/README.md +++ b/angular-sample-spa/README.md @@ -1,6 +1,6 @@ # IBM Cloud AppID React Sample App -The IBM Cloud AppID SDK can be used with React to create a secure single-page application. You will need an IBM Cloud App ID instance with a single-page application created. Use the clientId and discoveryEndpoint from the application credentials to initialize the AppID instance. +The IBM Cloud App ID SDK can be used with React to create a secure single-page application. You will need an IBM Cloud App ID instance with a single-page application created. Use the client ID and discovery endpoint from your application credentials to initialize the App ID instance. ## Prerequisites * Node.js version 8 or later @@ -10,20 +10,20 @@ The IBM Cloud AppID SDK can be used with React to create a secure single-page ap ## To run locally -* Clone the repository +1. Clone the repository. ``` -git clone +git clone https://github.com/ibm-cloud-security/appid-sample-code-snippets.git ``` -* Navigate to application workspace folder. +2. Navigate to application workspace folder. ``` -cd angular-sample-spa +cd angular-sample-app ``` -* To get the dpendencies for the app installed run +3. Install dependencies for the application. ``` npm install ``` -* To start the development server run +4. Start the development server. Navigate to http://localhost:4200 to access your application. ``` ng serve ``` diff --git a/angular-sample-spa/src/app/app.component.html b/angular-sample-spa/src/app/app.component.html index 36cc17b..c2e9a1c 100644 --- a/angular-sample-spa/src/app/app.component.html +++ b/angular-sample-spa/src/app/app.component.html @@ -1,40 +1,18 @@ -
- IBM Cloud AppID SDK Sample SPA -
-
-
- App ID Logo -

- Welcome to the
- IBM Cloud App ID SPA SDK
- Sample App -

- -
{{errorMessage}}
-
-
-
hint image
-
- Hint: To get started, click
- the Login button above to reveal
- the App ID login Pop-up window. -
-
-
-
-
-

{{userName}}

-

You've made your first authentication.

-
-
-

ID Token

-
-

{{idToken}}

-
-
-

User Information

-
-

{{userData}}

-
-
+ + +

Hi {{userName}}! You are now authenticated

+
{{errorMessage}}
diff --git a/angular-sample-spa/src/app/app.component.ts b/angular-sample-spa/src/app/app.component.ts index 6b04dcd..fe319be 100644 --- a/angular-sample-spa/src/app/app.component.ts +++ b/angular-sample-spa/src/app/app.component.ts @@ -6,31 +6,27 @@ import AppID from 'ibmcloud-appid-js'; templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) - export class AppComponent { - userName = '' - idToken = ''; - userData = ''; + userName = ''; errorMessage = ''; - style = 'show'; - displayState = 'hide'; - + buttonStyle = 'show'; + messageStyle = 'hide'; + errorStyle = 'hide'; async onLoginClick() { - const appid = new AppID(); + const appID = new AppID(); try { - await appid.init({ - clientId: '', + await appID.init({ + clientId: '', discoveryEndpoint: '' }); - const tokens = await appid.signin(); - const userInfo = await appid.getUserInfo(tokens.accessToken); + const tokens = await appID.signin(); const decodeIDTokens = tokens.idTokenPayload; - this.userName = 'Hi ' + decodeIDTokens.name + ', Congratulations!'; - this.idToken = JSON.stringify(decodeIDTokens); - this.userData = JSON.stringify(userInfo); - this.style = 'hide'; - this.displayState = 'show'; + this.userName = decodeIDTokens.name; + this.buttonStyle = 'hide'; + this.messageStyle = 'show'; + this.errorStyle = 'hide'; } catch (e) { + this.errorStyle = 'show'; this.errorMessage = e.message; } } From dad220f40f9425600aaaa820cdf708680d4b564b Mon Sep 17 00:00:00 2001 From: Bernie Date: Mon, 16 Dec 2019 08:26:47 -0700 Subject: [PATCH 06/20] Update on the README file --- react-sample-app/README.md | 138 +++++++++++++++++++++++++++++++++++-- 1 file changed, 134 insertions(+), 4 deletions(-) diff --git a/react-sample-app/README.md b/react-sample-app/README.md index 0538469..266873c 100644 --- a/react-sample-app/README.md +++ b/react-sample-app/README.md @@ -10,22 +10,152 @@ The IBM Cloud App ID SDK can be used with React to create a secure single-page a ## To run locally -1. Clone the repository. +1 Clone the repository. ``` git clone https://github.com/ibm-cloud-security/appid-sample-code-snippets.git ``` -2. Navigate to application workspace folder. +2 Navigate to application workspace folder. ``` cd react-sample-app ``` -3. Install dependencies for the application. +3 Install dependencies for the application. ``` npm install ``` -4. Start the development server. Navigate to http://localhost:3000 to access your application. +4 Start the development server. Navigate to http://localhost:3000 to access your application. ``` npm start ``` The app will automatically reload if you change any of the source files. + +## Detailed instructions on Creating your app + +1 Set up a frontend build pipeline by using create-react-app. Then move into the project directory. +``` +npx create-react-app my-app +cd my-app +``` +2 Install the IBM Cloud AppID SDK. +``` +npm install ibmcloud-appid-js +``` +3 In your code editor, in the src directory of the application, open the App.js file. Import App ID by adding the following code: +``` +import AppID from 'ibmcloud-appid-js'; +``` +4 In the main App() function, declare a new App ID instance with useMemo, which recomputes a memoized value when a dependency changes. +``` +const appID = React.useMemo(() => { +    return new AppID() +  }, []); +``` +5 Initialize App ID and add error handling. Add your client ID and discovery endpoint which can be found in the Applications tab of the App ID dashboard. +``` +const [errorState, setErrorState] = React.useState(false); +const [errorMessage, setErrorMessage] = React.useState(''); +(async () => { +    try { +      await appID.init({ +        clientId: '', +        discoveryEndpoint: '' +      }); +    } catch (e) { +      setErrorState(true); +      setErrorMessage(e.message); +    } +  })(); +``` +6 Create a login action that will execute when the login button is clicked. After a successful authentication, the welcomeDisplayState will be set to true and the userName will be set to the name returned in the App ID token. +``` +const [welcomeDisplayState, setWelcomeDisplayState] = React.useState(false); +const [loginButtonDisplayState, setLoginButtonDisplayState] = React.useState(true); +const [userName, setUserName] = React.useState(''); + + +const loginAction = async () => { +  try { +    const tokens = await appID.signin(); +    setErrorState(false); +    setLoginButtonDisplayState(false); +    setWelcomeDisplayState(true); +    setUserName(tokens.idTokenPayload.name); +  } catch (e) { +    setErrorState(true); +    setErrorMessage(e.message); +  } +}; +``` +7 Add a welcome div, the login button that calls the login action, and an error div. +``` +{welcomeDisplayState &&
Welcome {userName}! You are now authenticated.
} +{loginButtonDisplayState &&  +} +{errorState &&
{errorMessage}
} +``` +8 Save all of the files. Your entire App.js file should look like this: +``` +import React from 'react'; +import logo from './logo.svg'; +import './App.css'; +import AppID from 'ibmcloud-appid-js'; + +function App() { +  const appID = React.useMemo(() => { +  return new AppID() +   }, []); + +const [errorState, setErrorState] = React.useState(false); +const [errorMessage, setErrorMessage] = React.useState(''); + +(async () => { +  try { +    await appID.init({ +      'clientId': '', +      'discoveryEndpoint': '' +    }); +  } catch (e) { +    setErrorState(true); +    setErrorMessage(e.message); +  } +})(); + +const [welcomeDisplayState, setWelcomeDisplayState] = React.useState(false); +const [loginButtonDisplayState, setLoginButtonDisplayState] = React.useState(true); +const [userName, setUserName] = React.useState(''); + +const loginAction = async () => { +try { +    const tokens = await appID.signin(); +    setErrorState(false); +    setLoginButtonDisplayState(false); +    setWelcomeDisplayState(true); +    setUserName(tokens.idTokenPayload.name); +  } catch (e) { +    setErrorState(true); +    setErrorMessage(e.message); +  } +}; +  +return ( +   
+     
+        logo +        {welcomeDisplayState &&
Welcome {userName}! You are now authenticated.
} +        {loginButtonDisplayState &&  +Login} +        {errorState &&
{errorMessage}
} +     
+   
+); +} +export default App; +``` +9 Open your terminal. Run the following command to access your app from http://localhost:3000. +``` +npm start +``` + +Well done! You successfully integrated IBM Cloud App ID's SDK for SPA into a React application. From 2c428a7f101348982c3280fb6454b7f6b62fd6cb Mon Sep 17 00:00:00 2001 From: Bernie Date: Mon, 16 Dec 2019 09:43:42 -0700 Subject: [PATCH 07/20] Update on the README file --- angular-sample-spa/README.md | 88 +++++++++++++++++++++-- angular-sample-spa/src/styles.css | 111 ------------------------------ 2 files changed, 83 insertions(+), 116 deletions(-) diff --git a/angular-sample-spa/README.md b/angular-sample-spa/README.md index a78ceac..a3d525b 100644 --- a/angular-sample-spa/README.md +++ b/angular-sample-spa/README.md @@ -10,22 +10,100 @@ The IBM Cloud App ID SDK can be used with React to create a secure single-page a ## To run locally -1. Clone the repository. +1 Clone the repository. ``` git clone https://github.com/ibm-cloud-security/appid-sample-code-snippets.git ``` -2. Navigate to application workspace folder. +2 Navigate to application workspace folder. ``` cd angular-sample-app ``` -3. Install dependencies for the application. +3 Install dependencies for the application. ``` npm install ``` - -4. Start the development server. Navigate to http://localhost:4200 to access your application. +4 Start the development server. Navigate to http://localhost:4200 to access your application. ``` ng serve ``` The app will automatically reload if you change any of the source files. + +## Detailed instructions on Creating you application + + +1 Install the Angular CLI +``` +npm install -g @angular/cli +``` +2 Create a workspace and initial application and go to the workspace folder +``` +ng new angular-sample-spa +cd angular-sample-spa +``` +3 Install the IBM Cloud AppID SDK dependency using npm +``` +npm install ibmcloud-appid-js +``` + +4 In the src directory, go to the app folder and import App ID in the `app.component.ts` file, with the following code: +``` +import AppID from 'ibmcloud-appid-js'; +``` +5 In the AppComponent class initialize the states of the variables to be used in the application +``` +userName = ''; +errorMessage = ''; +buttonStyle = 'show'; +messageStyle = 'hide'; +errorStyle = 'hide' +``` +6 Create a loginAction function which when triggered will start the authentication flow and use tokens to get the user's information.  +``` +async onLoginClick() { +    const appID = new AppID(); +    try { +      await appID.init({ +        clientId: '', +        discoveryEndpoint: ' +      }); +      const tokens = await appID.signin(); + const decodeIDTokens = tokens.idTokenPayload; + this.userName = decodeIDTokens.name; + this.buttonStyle = 'hide'; + this.messageStyle = 'show'; + this.errorStyle = 'hide';     +    } catch (e) { + this.errorStyle = 'show'; + this.errorMessage = e.message; +    } +} +``` +7 In the `app.component.html` file, clear all the content in it and add the HTML and CSS code for the application. +``` + + + +

Hi {{userName}}! You are now authenticated

+
{{errorMessage}}
+``` +8 Save all the files and in your terminal, run the following command to access your app from http://localhost:4200. +``` +ng serve +``` +9 Make sure you register your redirect_uri (in this case http://localhost:3000/*) with App ID to ensure that only authorized clients are allowed to participate in the authorization workflow. This can be done on the App ID dashboard under the Manage Authentication tab in the Authentication Settings. Click [here](https://cloud.ibm.com/docs/services/appid?topic=appid-managing-idp#add-redirect-uri) for more details. + +Well done! You successfully integrated IBM Cloud App ID's SDK for SPA into an Angular application. diff --git a/angular-sample-spa/src/styles.css b/angular-sample-spa/src/styles.css index f7661b6..e69de29 100644 --- a/angular-sample-spa/src/styles.css +++ b/angular-sample-spa/src/styles.css @@ -1,111 +0,0 @@ -body { - margin: 0; - padding: 0; - max-width: 100%; - overflow-x: hidden; -} -.wrapper { - display: block; - background-color: #EBF0F7; - font-family: 'IBMPlexSans-SemiBold', sans-serif; - margin-bottom: 8%; - width: 100%; - height: 40px; - font-size: 14px; - color: #000000; - padding: 10px; - line-height: 40px; -} -@-moz-document url-prefix() { - .wrapper { - font-family: 'IBM Plex Sans SemiBold', 'Helvetica Neue', Arial, sans-serif; - } -} -.logo-icon { - display: block; - width: 70px; - height: 70px; - margin: 0 auto 20px; -} -#login { - font-family: 'IBMPlexSans-Medium', sans-serif; - font-size: 14px; - color: #FFFFFF; - letter-spacing: 0; - text-align: center; - background-color: #4178BE; - border: none; - padding: 10px 40px; - text-decoration: none; - cursor: pointer; - width: 158px; - height: 40px; - margin: 20px auto 0; -} -@-moz-document url-prefix() { - #login { - font-family: 'IBM Plex Sans Medium', 'Helvetica Neue', Arial, sans-serif; - } -} -#error { - padding-top: 20px; - font-size: 14px; - color: red; -} -.welcome-display { - display: block; - margin: 0 auto; - width: 30%; - height: auto; - font-family: 'IBMPlexSans-Light', sans-serif; - font-size: 1.5vw; - color: #152935; - letter-spacing: 0; - text-align: center; -} -@-moz-document url-prefix() { - .welcome-display { - font-family: 'IBM Plex Sans Light', 'Helvetica Neue', Arial, sans-serif; - } -} -.hintSection { - display: flex; - justify-content: center; - margin-top: 5%; - margin-bottom: 10%; -} -.flex-bottom { - font-family: 'IBMPlexSans-Medium', sans-serif; - font-size: 14px; - color: #42535C; - letter-spacing: 0; - line-height: 20px; - font-weight: normal; - flex: none; - margin-right: 5px; - margin-left: 5px; -} -@-moz-document url-prefix() { - .flex-bottom { - font-family: 'IBM Plex Sans Medium', sans-serif; - } -} -.hide { - display: none; -} -.show { - display: block; -} -.token-display, .info-display { - display: block; - width: 50%; - height: auto; - font-family: 'IBMPlexSans-Light', sans-serif; - font-size: 1vw; - color: #152935; - letter-spacing: 0; - word-break: break-all; - padding: 5px; - border-radius: 10px; - margin: 0 auto 15px; -} From 43c4659bf3ad7c9b9808bfee26e98d5df08538ae Mon Sep 17 00:00:00 2001 From: Bernie Date: Mon, 16 Dec 2019 09:53:37 -0700 Subject: [PATCH 08/20] Update on the README file --- react-sample-app/README.md | 105 +++++++++++++++++++------------------ 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/react-sample-app/README.md b/react-sample-app/README.md index 266873c..b85a039 100644 --- a/react-sample-app/README.md +++ b/react-sample-app/README.md @@ -32,7 +32,7 @@ The app will automatically reload if you change any of the source files. ## Detailed instructions on Creating your app -1 Set up a frontend build pipeline by using create-react-app. Then move into the project directory. +1 Set up a frontend build pipeline using create-react-app. Then move into the project directory. ``` npx create-react-app my-app cd my-app @@ -49,9 +49,9 @@ import AppID from 'ibmcloud-appid-js'; ``` const appID = React.useMemo(() => {     return new AppID() -  }, []); +}, []); ``` -5 Initialize App ID and add error handling. Add your client ID and discovery endpoint which can be found in the Applications tab of the App ID dashboard. +5 Initialize App ID and add error handling. Add your [client ID and discovery endpoint](https://cloud.ibm.com/docs/services/appid?topic=appid-single-page#create-spa-credentials) which can be found in the Applications tab of the App ID dashboard. ``` const [errorState, setErrorState] = React.useState(false); const [errorMessage, setErrorMessage] = React.useState(''); @@ -65,7 +65,7 @@ const [errorMessage, setErrorMessage] = React.useState('');       setErrorState(true);       setErrorMessage(e.message);     } -  })(); +})(); ``` 6 Create a login action that will execute when the login button is clicked. After a successful authentication, the welcomeDisplayState will be set to true and the userName will be set to the name returned in the App ID token. ``` @@ -73,7 +73,6 @@ const [welcomeDisplayState, setWelcomeDisplayState] = React.useState(false); const [loginButtonDisplayState, setLoginButtonDisplayState] = React.useState(true); const [userName, setUserName] = React.useState(''); - const loginAction = async () => {   try {     const tokens = await appID.signin(); @@ -102,54 +101,55 @@ import './App.css'; import AppID from 'ibmcloud-appid-js'; function App() { -  const appID = React.useMemo(() => { -  return new AppID() -   }, []); - -const [errorState, setErrorState] = React.useState(false); -const [errorMessage, setErrorMessage] = React.useState(''); - -(async () => { -  try { -    await appID.init({ -      'clientId': '', -      'discoveryEndpoint': '' -    }); -  } catch (e) { -    setErrorState(true); -    setErrorMessage(e.message); -  } -})(); - -const [welcomeDisplayState, setWelcomeDisplayState] = React.useState(false); -const [loginButtonDisplayState, setLoginButtonDisplayState] = React.useState(true); -const [userName, setUserName] = React.useState(''); - -const loginAction = async () => { -try { -    const tokens = await appID.signin(); -    setErrorState(false); -    setLoginButtonDisplayState(false); -    setWelcomeDisplayState(true); -    setUserName(tokens.idTokenPayload.name); -  } catch (e) { -    setErrorState(true); -    setErrorMessage(e.message); -  } -}; + const appID = React.useMemo(() => { +  return new AppID() + }, []); + + const [errorState, setErrorState] = React.useState(false); + const [errorMessage, setErrorMessage] = React.useState(''); + + (async () => { +   try { +     await appID.init({ +       'clientId': '', +       'discoveryEndpoint': '' +     }); +   } catch (e) { +     setErrorState(true); +     setErrorMessage(e.message); +   } + })(); + + const [welcomeDisplayState, setWelcomeDisplayState] = React.useState(false); + const [loginButtonDisplayState, setLoginButtonDisplayState] = React.useState(true); + const [userName, setUserName] = React.useState(''); + + const loginAction = async () => { + try { +     const tokens = await appID.signin(); +     setErrorState(false); +     setLoginButtonDisplayState(false); +     setWelcomeDisplayState(true); +     setUserName(tokens.idTokenPayload.name); +   } catch (e) { +     setErrorState(true); +     setErrorMessage(e.message); +   } + };   -return ( -   
-     
-        logo -        {welcomeDisplayState &&
Welcome {userName}! You are now authenticated.
} -        {loginButtonDisplayState &&  -Login} -        {errorState &&
{errorMessage}
} -     
-   
-); + return ( +    
+      
+         logo +         {welcomeDisplayState &&
Welcome {userName}! You are now authenticated.
} +         {loginButtonDisplayState &&  + Login} +         {errorState &&
{errorMessage}
} +      
+    
+ ); } export default App; ``` @@ -157,5 +157,6 @@ export default App; ``` npm start ``` +10 Make sure you register your redirect_uri (in this case http://localhost:3000/*) with App ID to ensure that only authorized clients are allowed to participate in the authorization workflow. This can be done on the App ID dashboard under the Manage Authentication tab in the Authentication Settings. Click [here](https://cloud.ibm.com/docs/services/appid?topic=appid-managing-idp#add-redirect-uri) for more details. Well done! You successfully integrated IBM Cloud App ID's SDK for SPA into a React application. From 0311008994b4960814b20feaa21b929201fc4e60 Mon Sep 17 00:00:00 2001 From: Bernie Date: Fri, 24 Jan 2020 07:27:44 -0700 Subject: [PATCH 09/20] Fixed styling on the angular sample app --- angular-sample-spa/src/app/app.component.html | 4 ++-- angular-sample-spa/src/app/app.component.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/angular-sample-spa/src/app/app.component.html b/angular-sample-spa/src/app/app.component.html index c2e9a1c..7b1cea4 100644 --- a/angular-sample-spa/src/app/app.component.html +++ b/angular-sample-spa/src/app/app.component.html @@ -10,9 +10,9 @@ -

Hi {{userName}}! You are now authenticated

+

Hi {{userName}} congratulations! You are now authenticated

{{errorMessage}}
diff --git a/angular-sample-spa/src/app/app.component.ts b/angular-sample-spa/src/app/app.component.ts index fe319be..40b51a2 100644 --- a/angular-sample-spa/src/app/app.component.ts +++ b/angular-sample-spa/src/app/app.component.ts @@ -16,7 +16,7 @@ export class AppComponent { const appID = new AppID(); try { await appID.init({ - clientId: '', + clientId: '', discoveryEndpoint: '' }); const tokens = await appID.signin(); From d997e687109c9296b8143c5b225a0c8d93a17f4d Mon Sep 17 00:00:00 2001 From: Bernie Date: Fri, 24 Jan 2020 07:31:19 -0700 Subject: [PATCH 10/20] Update the README file --- angular-sample-spa/README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/angular-sample-spa/README.md b/angular-sample-spa/README.md index a3d525b..a1eb383 100644 --- a/angular-sample-spa/README.md +++ b/angular-sample-spa/README.md @@ -82,22 +82,22 @@ async onLoginClick() { 7 In the `app.component.html` file, clear all the content in it and add the HTML and CSS code for the application. ``` -

Hi {{userName}}! You are now authenticated

+

Hi {{userName}} congratulations! You are now authenticated

{{errorMessage}}
``` 8 Save all the files and in your terminal, run the following command to access your app from http://localhost:4200. From da44214e546dffe1383121ba2d1165af6b4c9ebb Mon Sep 17 00:00:00 2001 From: Bernie Date: Fri, 24 Jan 2020 08:18:21 -0700 Subject: [PATCH 11/20] Fixed styling issue on the angular sample app --- angular-sample-spa/README.md | 21 +++++++------------ angular-sample-spa/src/app/app.component.html | 20 +++++++----------- angular-sample-spa/src/app/app.component.ts | 1 + 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/angular-sample-spa/README.md b/angular-sample-spa/README.md index a1eb383..b847b97 100644 --- a/angular-sample-spa/README.md +++ b/angular-sample-spa/README.md @@ -82,23 +82,18 @@ async onLoginClick() { 7 In the `app.component.html` file, clear all the content in it and add the HTML and CSS code for the application. ``` -

Hi {{userName}} congratulations! You are now authenticated

-
{{errorMessage}}
+

Hi {{userName}} congratulations! You are now authenticated

+
{{errorMessage}}
+ ``` 8 Save all the files and in your terminal, run the following command to access your app from http://localhost:4200. ``` diff --git a/angular-sample-spa/src/app/app.component.html b/angular-sample-spa/src/app/app.component.html index 7b1cea4..b12884a 100644 --- a/angular-sample-spa/src/app/app.component.html +++ b/angular-sample-spa/src/app/app.component.html @@ -1,18 +1,12 @@ -

Hi {{userName}} congratulations! You are now authenticated

-
{{errorMessage}}
+

Hi {{userName}} congratulations! You are now authenticated

+
{{errorMessage}}
diff --git a/angular-sample-spa/src/app/app.component.ts b/angular-sample-spa/src/app/app.component.ts index 40b51a2..9f500f2 100644 --- a/angular-sample-spa/src/app/app.component.ts +++ b/angular-sample-spa/src/app/app.component.ts @@ -7,6 +7,7 @@ import AppID from 'ibmcloud-appid-js'; styleUrls: ['./app.component.css'] }) export class AppComponent { + title = 'angular-sample-spa'; userName = ''; errorMessage = ''; buttonStyle = 'show'; From 4ae5b8e865ae256acb113b9a08428813946ec7cc Mon Sep 17 00:00:00 2001 From: Bernie Date: Mon, 27 Jan 2020 15:12:32 -0700 Subject: [PATCH 12/20] Changed the location of the CSS styles --- angular-sample-spa/README.md | 8 +++----- angular-sample-spa/src/app/app.component.css | 16 ++++++++++++++++ angular-sample-spa/src/app/app.component.html | 12 +++--------- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/angular-sample-spa/README.md b/angular-sample-spa/README.md index b847b97..2f6090e 100644 --- a/angular-sample-spa/README.md +++ b/angular-sample-spa/README.md @@ -1,4 +1,4 @@ -# IBM Cloud AppID React Sample App +# IBM Cloud AppID Angular Sample App The IBM Cloud App ID SDK can be used with React to create a secure single-page application. You will need an IBM Cloud App ID instance with a single-page application created. Use the client ID and discovery endpoint from your application credentials to initialize the App ID instance. @@ -16,7 +16,7 @@ git clone https://github.com/ibm-cloud-security/appid-sample-code-snippets.git ``` 2 Navigate to application workspace folder. ``` -cd angular-sample-app +cd angular-sample-spa ``` 3 Install dependencies for the application. ``` @@ -27,9 +27,7 @@ npm install ng serve ``` -The app will automatically reload if you change any of the source files. - -## Detailed instructions on Creating you application +## Detailed instructions on creating your application 1 Install the Angular CLI diff --git a/angular-sample-spa/src/app/app.component.css b/angular-sample-spa/src/app/app.component.css index e69de29..da3281f 100644 --- a/angular-sample-spa/src/app/app.component.css +++ b/angular-sample-spa/src/app/app.component.css @@ -0,0 +1,16 @@ +.hide {display: none;} +.show {display: block;} +#button { + background-color: #4178BE; + width: 270px; + height: 40px; + color: #FFFFFF; + font-size: 14px; + border: none; + margin: 30px 15px; +} +#message {margin-left: 15px;} +#error { + margin-left: 15px; + color: red; +} diff --git a/angular-sample-spa/src/app/app.component.html b/angular-sample-spa/src/app/app.component.html index b12884a..8be2680 100644 --- a/angular-sample-spa/src/app/app.component.html +++ b/angular-sample-spa/src/app/app.component.html @@ -1,12 +1,6 @@ - - -

Hi {{userName}} congratulations! You are now authenticated

-
{{errorMessage}}
+

Hi {{userName}} congratulations! You are now authenticated

+
{{errorMessage}}
From 251942d33ea371cce0b92114ca3bb89d9c183218 Mon Sep 17 00:00:00 2001 From: Bernie Date: Mon, 27 Jan 2020 15:17:48 -0700 Subject: [PATCH 13/20] Update on the README file --- angular-sample-spa/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/angular-sample-spa/README.md b/angular-sample-spa/README.md index 2f6090e..0580ba5 100644 --- a/angular-sample-spa/README.md +++ b/angular-sample-spa/README.md @@ -97,6 +97,6 @@ async onLoginClick() { ``` ng serve ``` -9 Make sure you register your redirect_uri (in this case http://localhost:3000/*) with App ID to ensure that only authorized clients are allowed to participate in the authorization workflow. This can be done on the App ID dashboard under the Manage Authentication tab in the Authentication Settings. Click [here](https://cloud.ibm.com/docs/services/appid?topic=appid-managing-idp#add-redirect-uri) for more details. +9 Make sure you register your redirect_uri (in this case http://localhost:4200/*) with App ID to ensure that only authorized clients are allowed to participate in the authorization workflow. This can be done on the App ID dashboard under the Manage Authentication tab in the Authentication Settings. Click [here](https://cloud.ibm.com/docs/services/appid?topic=appid-managing-idp#add-redirect-uri) for more details. Well done! You successfully integrated IBM Cloud App ID's SDK for SPA into an Angular application. From 8c864bd849c1660be2c96ddb4027a060d813f8f1 Mon Sep 17 00:00:00 2001 From: Bernie Date: Wed, 29 Jan 2020 14:18:17 -0700 Subject: [PATCH 14/20] Updated the sample app --- angular-sample-spa/README.md | 75 +------------------ angular-sample-spa/src/app/app.component.css | 16 ---- angular-sample-spa/src/app/app.component.html | 9 +-- angular-sample-spa/src/app/app.component.ts | 33 +++----- angular-sample-spa/src/app/app.module.ts | 8 +- .../src/app/home/home.component.css | 70 +++++++++++++++++ .../src/app/home/home.component.html | 29 +++++++ .../src/app/home/home.component.spec.ts | 25 +++++++ .../src/app/home/home.component.ts | 48 ++++++++++++ .../src/app/navbar/navbar.component.css | 17 +++++ .../src/app/navbar/navbar.component.html | 3 + .../src/app/navbar/navbar.component.spec.ts | 25 +++++++ .../src/app/navbar/navbar.component.ts | 15 ++++ .../src/app/welcome/welcome.component.css | 35 +++++++++ .../src/app/welcome/welcome.component.html | 23 ++++++ .../src/app/welcome/welcome.component.spec.ts | 25 +++++++ .../src/app/welcome/welcome.component.ts | 49 ++++++++++++ .../src/assets/images/20@2x.svg | 11 +++ angular-sample-spa/src/styles.css | 74 ++++++++++++++++++ 19 files changed, 470 insertions(+), 120 deletions(-) create mode 100644 angular-sample-spa/src/app/home/home.component.css create mode 100644 angular-sample-spa/src/app/home/home.component.html create mode 100644 angular-sample-spa/src/app/home/home.component.spec.ts create mode 100644 angular-sample-spa/src/app/home/home.component.ts create mode 100644 angular-sample-spa/src/app/navbar/navbar.component.css create mode 100644 angular-sample-spa/src/app/navbar/navbar.component.html create mode 100644 angular-sample-spa/src/app/navbar/navbar.component.spec.ts create mode 100644 angular-sample-spa/src/app/navbar/navbar.component.ts create mode 100644 angular-sample-spa/src/app/welcome/welcome.component.css create mode 100644 angular-sample-spa/src/app/welcome/welcome.component.html create mode 100644 angular-sample-spa/src/app/welcome/welcome.component.spec.ts create mode 100644 angular-sample-spa/src/app/welcome/welcome.component.ts create mode 100644 angular-sample-spa/src/assets/images/20@2x.svg diff --git a/angular-sample-spa/README.md b/angular-sample-spa/README.md index 0580ba5..1d05c7c 100644 --- a/angular-sample-spa/README.md +++ b/angular-sample-spa/README.md @@ -1,6 +1,6 @@ # IBM Cloud AppID Angular Sample App -The IBM Cloud App ID SDK can be used with React to create a secure single-page application. You will need an IBM Cloud App ID instance with a single-page application created. Use the client ID and discovery endpoint from your application credentials to initialize the App ID instance. +The IBM Cloud App ID SDK can be used with Angular to create a secure single-page application. You will need an IBM Cloud App ID instance with a single-page application created. Use the client ID and discovery endpoint from your application credentials to initialize the App ID instance. ## Prerequisites * Node.js version 8 or later @@ -26,77 +26,6 @@ npm install ``` ng serve ``` - -## Detailed instructions on creating your application - - -1 Install the Angular CLI -``` -npm install -g @angular/cli -``` -2 Create a workspace and initial application and go to the workspace folder -``` -ng new angular-sample-spa -cd angular-sample-spa -``` -3 Install the IBM Cloud AppID SDK dependency using npm -``` -npm install ibmcloud-appid-js -``` - -4 In the src directory, go to the app folder and import App ID in the `app.component.ts` file, with the following code: -``` -import AppID from 'ibmcloud-appid-js'; -``` -5 In the AppComponent class initialize the states of the variables to be used in the application -``` -userName = ''; -errorMessage = ''; -buttonStyle = 'show'; -messageStyle = 'hide'; -errorStyle = 'hide' -``` -6 Create a loginAction function which when triggered will start the authentication flow and use tokens to get the user's information.  -``` -async onLoginClick() { -    const appID = new AppID(); -    try { -      await appID.init({ -        clientId: '', -        discoveryEndpoint: ' -      }); -      const tokens = await appID.signin(); - const decodeIDTokens = tokens.idTokenPayload; - this.userName = decodeIDTokens.name; - this.buttonStyle = 'hide'; - this.messageStyle = 'show'; - this.errorStyle = 'hide';     -    } catch (e) { - this.errorStyle = 'show'; - this.errorMessage = e.message; -    } -} -``` -7 In the `app.component.html` file, clear all the content in it and add the HTML and CSS code for the application. -``` - - - -

Hi {{userName}} congratulations! You are now authenticated

-
{{errorMessage}}
- -``` -8 Save all the files and in your terminal, run the following command to access your app from http://localhost:4200. -``` -ng serve -``` -9 Make sure you register your redirect_uri (in this case http://localhost:4200/*) with App ID to ensure that only authorized clients are allowed to participate in the authorization workflow. This can be done on the App ID dashboard under the Manage Authentication tab in the Authentication Settings. Click [here](https://cloud.ibm.com/docs/services/appid?topic=appid-managing-idp#add-redirect-uri) for more details. +5 Make sure you register your redirect_uri (in this case http://localhost:4200/*) with App ID to ensure that only authorized clients are allowed to participate in the authorization workflow. This can be done on the App ID dashboard under the Manage Authentication tab in the Authentication Settings. Click [here](https://cloud.ibm.com/docs/services/appid?topic=appid-managing-idp#add-redirect-uri) for more details. Well done! You successfully integrated IBM Cloud App ID's SDK for SPA into an Angular application. diff --git a/angular-sample-spa/src/app/app.component.css b/angular-sample-spa/src/app/app.component.css index da3281f..e69de29 100644 --- a/angular-sample-spa/src/app/app.component.css +++ b/angular-sample-spa/src/app/app.component.css @@ -1,16 +0,0 @@ -.hide {display: none;} -.show {display: block;} -#button { - background-color: #4178BE; - width: 270px; - height: 40px; - color: #FFFFFF; - font-size: 14px; - border: none; - margin: 30px 15px; -} -#message {margin-left: 15px;} -#error { - margin-left: 15px; - color: red; -} diff --git a/angular-sample-spa/src/app/app.component.html b/angular-sample-spa/src/app/app.component.html index 8be2680..96aeb73 100644 --- a/angular-sample-spa/src/app/app.component.html +++ b/angular-sample-spa/src/app/app.component.html @@ -1,6 +1,3 @@ - -

Hi {{userName}} congratulations! You are now authenticated

-
{{errorMessage}}
+ + + diff --git a/angular-sample-spa/src/app/app.component.ts b/angular-sample-spa/src/app/app.component.ts index 9f500f2..d4d06a3 100644 --- a/angular-sample-spa/src/app/app.component.ts +++ b/angular-sample-spa/src/app/app.component.ts @@ -1,5 +1,4 @@ import { Component } from '@angular/core'; -import AppID from 'ibmcloud-appid-js'; @Component({ selector: 'app-root', @@ -7,28 +6,14 @@ import AppID from 'ibmcloud-appid-js'; styleUrls: ['./app.component.css'] }) export class AppComponent { - title = 'angular-sample-spa'; - userName = ''; - errorMessage = ''; - buttonStyle = 'show'; - messageStyle = 'hide'; - errorStyle = 'hide'; - async onLoginClick() { - const appID = new AppID(); - try { - await appID.init({ - clientId: '', - discoveryEndpoint: '' - }); - const tokens = await appID.signin(); - const decodeIDTokens = tokens.idTokenPayload; - this.userName = decodeIDTokens.name; - this.buttonStyle = 'hide'; - this.messageStyle = 'show'; - this.errorStyle = 'hide'; - } catch (e) { - this.errorStyle = 'show'; - this.errorMessage = e.message; - } + displayStateStatus = 'hide'; + userNameStatus = ''; + idTokenStatus = ''; + userDataStatus = ''; + onChangeState(value) { + this.displayStateStatus = 'show'; + this.userNameStatus = value.userName; + this.idTokenStatus = value.idToken; + this.userDataStatus = value.userData; } } diff --git a/angular-sample-spa/src/app/app.module.ts b/angular-sample-spa/src/app/app.module.ts index f657163..ae6ebce 100644 --- a/angular-sample-spa/src/app/app.module.ts +++ b/angular-sample-spa/src/app/app.module.ts @@ -2,10 +2,16 @@ import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; +import { HomeComponent } from './home/home.component'; +import { NavbarComponent } from './navbar/navbar.component'; +import { WelcomeComponent } from './welcome/welcome.component'; @NgModule({ declarations: [ - AppComponent + AppComponent, + HomeComponent, + NavbarComponent, + WelcomeComponent ], imports: [ BrowserModule diff --git a/angular-sample-spa/src/app/home/home.component.css b/angular-sample-spa/src/app/home/home.component.css new file mode 100644 index 0000000..02ef13e --- /dev/null +++ b/angular-sample-spa/src/app/home/home.component.css @@ -0,0 +1,70 @@ +.collapsibleButton { + display: flex; + margin: 0 auto; + cursor: pointer; + padding: 15px; + width: 700px; + border: none; + outline: none; + font-size: 14px; + text-align: left; + padding: 15px; + font-family: 'IBMPlexSans-Medium', sans-serif; + box-shadow: 0px -1px 5px 0px rgba(0, 0, 0, 0.15); +} +@-moz-document url-prefix() { + .collapsibleButton { + font-family: 'IBM Plex Sans Medium', sans-serif; + } +} + +.collapsibleButtonClicked { + display: flex; + margin: 0 auto; + cursor: pointer; + padding: 15px; + margin-top: 10px; + width: 800px; + border: none; + outline: none; + font-size: 14px; + text-align: left; + padding: 15px; + font-family: 'IBMPlexSans-Medium', sans-serif; + box-shadow: 0px -1px 5px 0px rgba(0, 0, 0, 0.15); +} +@-moz-document url-prefix() { + .collapsibleButtonClicked { + font-family: 'IBM Plex Sans Medium', sans-serif; + } +} + +.active { + transform: rotate(180deg); + margin-right: 20px; +} +.expand { + transform: rotate(0deg); + margin-right: 20px; +} +.contentHidden { + display: none; +} + +.contentShown { + display: block; + overflow: hidden; + padding: 15px; + width: 770px; + margin: 0 auto; + margin-bottom: 20px; + font-family: 'IBMPlexSans-light', sans-serif; + font-size: 1vw; + word-break: break-all; + box-shadow: 0px -1px 5px 0px rgba(0, 0, 0, 0.15); +} +@-moz-document url-prefix() { + .contentShown { + font-family: 'IBM Plex Sans Light', sans-serif; + } +} diff --git a/angular-sample-spa/src/app/home/home.component.html b/angular-sample-spa/src/app/home/home.component.html new file mode 100644 index 0000000..bd23086 --- /dev/null +++ b/angular-sample-spa/src/app/home/home.component.html @@ -0,0 +1,29 @@ +
+
+

{{userName}}

+

You've made your first authentication.

+
+
+ +
{{idToken}}
+
+
+ +
{{userData}}
+
+
+
hint image
+
+ Hint: To view your ID Token
+ and User Information, click
+ on the arrows above. +
+
+
+ diff --git a/angular-sample-spa/src/app/home/home.component.spec.ts b/angular-sample-spa/src/app/home/home.component.spec.ts new file mode 100644 index 0000000..490e81b --- /dev/null +++ b/angular-sample-spa/src/app/home/home.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { HomeComponent } from './home.component'; + +describe('HomeComponent', () => { + let component: HomeComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ HomeComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(HomeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/angular-sample-spa/src/app/home/home.component.ts b/angular-sample-spa/src/app/home/home.component.ts new file mode 100644 index 0000000..aaeac66 --- /dev/null +++ b/angular-sample-spa/src/app/home/home.component.ts @@ -0,0 +1,48 @@ +import { Component, Input} from '@angular/core'; + +@Component({ + selector: 'app-home', + templateUrl: './home.component.html', + styleUrls: ['./home.component.css'] +}) +export class HomeComponent { + @Input() displayState: string; + @Input() userName: string; + @Input() idToken: string; + @Input() userData: string; + tokenContentClass = 'contentHidden'; + tokenButtonClass = 'collapsibleButton'; + tokenImageClass = 'expand'; + infoContentClass = 'contentHidden'; + infoButtonClass = 'collapsibleButton'; + infoImageClass = 'expand'; + tokenState = true; + infoState = true; + onTokenClick() { + if (this.tokenState) { + this.tokenContentClass = 'contentShown'; + this.tokenButtonClass = 'collapsibleButtonClicked'; + this.tokenImageClass = 'active'; + this.tokenState = false; + } else { + this.tokenContentClass = 'contentHidden'; + this.tokenButtonClass = 'collapsibleButton'; + this.tokenImageClass = 'expand'; + this.tokenState = true; + } + } + onInfoClick() { + if (this.infoState) { + this.infoContentClass = 'contentShown'; + this.infoButtonClass = 'collapsibleButtonClicked'; + this.infoImageClass = 'active'; + this.infoState = false; + } else { + this.infoContentClass = 'contentHidden'; + this.infoButtonClass = 'collapsibleButton'; + this.infoImageClass = 'expand'; + this.infoState = true; + } + } +} + diff --git a/angular-sample-spa/src/app/navbar/navbar.component.css b/angular-sample-spa/src/app/navbar/navbar.component.css new file mode 100644 index 0000000..a327fe3 --- /dev/null +++ b/angular-sample-spa/src/app/navbar/navbar.component.css @@ -0,0 +1,17 @@ +.wrapper { + display: block; + background-color: #EBF0F7; + font-family: 'IBMPlexSans-SemiBold', sans-serif; + margin-bottom: 8%; + width: 100%; + height: 40px; + font-size: 14px; + color: #000000; + padding: 10px; + line-height: 40px; +} +@-moz-document url-prefix() { + .wrapper { + font-family: 'IBM Plex Sans SemiBold', 'Helvetica Neue', Arial, sans-serif; + } +} diff --git a/angular-sample-spa/src/app/navbar/navbar.component.html b/angular-sample-spa/src/app/navbar/navbar.component.html new file mode 100644 index 0000000..f3d213a --- /dev/null +++ b/angular-sample-spa/src/app/navbar/navbar.component.html @@ -0,0 +1,3 @@ +
+ IBM Cloud AppID SDK Sample SPA +
diff --git a/angular-sample-spa/src/app/navbar/navbar.component.spec.ts b/angular-sample-spa/src/app/navbar/navbar.component.spec.ts new file mode 100644 index 0000000..9032ad2 --- /dev/null +++ b/angular-sample-spa/src/app/navbar/navbar.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { NavbarComponent } from './navbar.component'; + +describe('NavbarComponent', () => { + let component: NavbarComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ NavbarComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(NavbarComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/angular-sample-spa/src/app/navbar/navbar.component.ts b/angular-sample-spa/src/app/navbar/navbar.component.ts new file mode 100644 index 0000000..8e29f4e --- /dev/null +++ b/angular-sample-spa/src/app/navbar/navbar.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'app-navbar', + templateUrl: './navbar.component.html', + styleUrls: ['./navbar.component.css'] +}) +export class NavbarComponent implements OnInit { + + constructor() { } + + ngOnInit() { + } + +} diff --git a/angular-sample-spa/src/app/welcome/welcome.component.css b/angular-sample-spa/src/app/welcome/welcome.component.css new file mode 100644 index 0000000..32da851 --- /dev/null +++ b/angular-sample-spa/src/app/welcome/welcome.component.css @@ -0,0 +1,35 @@ +.logo-icon { + display: block; + width: 70px; + height: 70px; + margin: 0 auto; + margin-bottom: 20px; +} +#login { + font-family: 'IBMPlexSans-Medium', sans-serif; + font-size: 14px; + color: #FFFFFF; + letter-spacing: 0; + text-align: center; + background-color: #4178BE; + border: none; + padding: 10px 40px; + text-decoration: none; + cursor: pointer; + width: 158px; + height: 40px; + margin: 0 auto; + margin-top: 20px; +} +@-moz-document url-prefix() { + #login { + font-family: 'IBM Plex Sans Medium', 'Helvetica Neue', Arial, sans-serif; + } +} +#error { + padding-top: 20px; + font-size: 14px; + color: red; +} + + diff --git a/angular-sample-spa/src/app/welcome/welcome.component.html b/angular-sample-spa/src/app/welcome/welcome.component.html new file mode 100644 index 0000000..c7da9e9 --- /dev/null +++ b/angular-sample-spa/src/app/welcome/welcome.component.html @@ -0,0 +1,23 @@ +
+
+
+ App ID Logo +

+ Welcome to the
+ IBM Cloud App ID SPA SDK
+ Sample App +

+
+
+ +
{{errorMessage}}
+
+
+
hint image
+
+ Hint: To get started, click
+ the Login button above to reveal
+ the App ID login Pop-up window. +
+
+
diff --git a/angular-sample-spa/src/app/welcome/welcome.component.spec.ts b/angular-sample-spa/src/app/welcome/welcome.component.spec.ts new file mode 100644 index 0000000..eb910c6 --- /dev/null +++ b/angular-sample-spa/src/app/welcome/welcome.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { WelcomeComponent } from './welcome.component'; + +describe('WelcomeComponent', () => { + let component: WelcomeComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ WelcomeComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(WelcomeComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/angular-sample-spa/src/app/welcome/welcome.component.ts b/angular-sample-spa/src/app/welcome/welcome.component.ts new file mode 100644 index 0000000..1ca4e6e --- /dev/null +++ b/angular-sample-spa/src/app/welcome/welcome.component.ts @@ -0,0 +1,49 @@ +import { Component, Output, EventEmitter, OnInit } from '@angular/core'; +import AppID from 'ibmcloud-appid-js'; + +@Component({ + selector: 'app-welcome', + templateUrl: './welcome.component.html', + styleUrls: ['./welcome.component.css'] +}) + +export class WelcomeComponent implements OnInit { + style = 'show'; + spinner = 'hide'; + buttonDisplay = 'show'; + errorStyle = 'hide'; + errorMessage = ''; + appid = new AppID(); + @Output() changeState = new EventEmitter(); + async ngOnInit() { + try { + await this.appid.init({ + clientId: '1b0e3658-fc1f-402e-843c-18402d4dbe58', + discoveryEndpoint: 'https://eu-gb.appid.test.cloud.ibm.com/oauth/v4/5b1eb5f1-34bd-41fd-b6dd-e257c188a4dd/.well-known/openid-configuration' + }); + } catch (e) { + this.errorMessage = e.message; + this.errorStyle = 'show'; + } + } + async onLoginClick() { + try { + this.buttonDisplay = 'hide'; + this.spinner = 'show'; + const tokens = await this.appid.signin(); + const userInfo = await this.appid.getUserInfo(tokens.accessToken); + const decodeIDTokens = tokens.idTokenPayload; + const userName = 'Hi ' + decodeIDTokens.name + ', Congratulations!'; + const idToken = JSON.stringify(decodeIDTokens); + const userData = JSON.stringify(userInfo); + this.style = 'hide'; + this.changeState.emit({userName, idToken, userData}); + } catch (e) { + this.errorMessage = e.message; + this.spinner = 'hide'; + this.errorStyle = 'show'; + this.buttonDisplay = 'show'; + + } + } +} diff --git a/angular-sample-spa/src/assets/images/20@2x.svg b/angular-sample-spa/src/assets/images/20@2x.svg new file mode 100644 index 0000000..7978fd9 --- /dev/null +++ b/angular-sample-spa/src/assets/images/20@2x.svg @@ -0,0 +1,11 @@ + + + + Actions / Navigation / chevron--down / 20@2x + Created with Sketch. + + + + + + \ No newline at end of file diff --git a/angular-sample-spa/src/styles.css b/angular-sample-spa/src/styles.css index e69de29..0b404eb 100644 --- a/angular-sample-spa/src/styles.css +++ b/angular-sample-spa/src/styles.css @@ -0,0 +1,74 @@ +body { + margin: 0; + padding: 0; + max-width: 100%; + overflow-x: hidden; +} +.welcome-display { + display: block; + margin: 0 auto; + width: 30%; + height: auto; + font-family: 'IBMPlexSans-Light', sans-serif; + font-size: 1.5vw; + color: #152935; + letter-spacing: 0; + text-align: center; +} +@-moz-document url-prefix() { + .welcome-display { + font-family: 'IBM Plex Sans Light', 'Helvetica Neue', Arial, sans-serif; + } +} +.hintSection { + display: flex; + justify-content: center; + margin-top: 5%; + margin-bottom: 10%; +} +.flex-bottom { + font-family: 'IBMPlexSans-Medium', sans-serif; + font-size: 14px; + color: #42535C; + letter-spacing: 0; + line-height: 20px; + font-weight: normal; + flex: none; + margin-right: 5px; + margin-left: 5px; +} +@-moz-document url-prefix() { + .flex-bottom { + font-family: 'IBM Plex Sans Medium', sans-serif; + } +} +.hide { + display: none; +} + +.show { + display: block; +} + +.loader { + /* display: block; */ + margin: 0 auto; + border: 16px solid #f3f3f3; + border-radius: 50%; + border-top: 16px solid #EBF0F7; + border-bottom: 16px solid #EBF0F7; + width: 60px; + height: 60px; + -webkit-animation: spin 2s linear infinite; + animation: spin 2s linear infinite; + } + + @-webkit-keyframes spin { + 0% { -webkit-transform: rotate(0deg); } + 100% { -webkit-transform: rotate(360deg); } + } + + @keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } + } From 1346d6b52b6e053552ddff4d7941625471eb295f Mon Sep 17 00:00:00 2001 From: Bernie Date: Wed, 29 Jan 2020 14:33:38 -0700 Subject: [PATCH 15/20] Removed credentials --- angular-sample-spa/src/app/welcome/welcome.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/angular-sample-spa/src/app/welcome/welcome.component.ts b/angular-sample-spa/src/app/welcome/welcome.component.ts index 1ca4e6e..862b5e4 100644 --- a/angular-sample-spa/src/app/welcome/welcome.component.ts +++ b/angular-sample-spa/src/app/welcome/welcome.component.ts @@ -18,8 +18,8 @@ export class WelcomeComponent implements OnInit { async ngOnInit() { try { await this.appid.init({ - clientId: '1b0e3658-fc1f-402e-843c-18402d4dbe58', - discoveryEndpoint: 'https://eu-gb.appid.test.cloud.ibm.com/oauth/v4/5b1eb5f1-34bd-41fd-b6dd-e257c188a4dd/.well-known/openid-configuration' + clientId: '', + discoveryEndpoint: '' }); } catch (e) { this.errorMessage = e.message; From 5a1eebd3b3fe5359e01549ae7bd3796968077834 Mon Sep 17 00:00:00 2001 From: Bernie Date: Thu, 30 Jan 2020 04:32:29 -0700 Subject: [PATCH 16/20] Fixed some styling --- angular-sample-spa/src/app/home/home.component.html | 6 +++--- angular-sample-spa/src/app/welcome/welcome.component.html | 4 ++-- angular-sample-spa/src/assets/{images => }/20@2x.svg | 0 angular-sample-spa/src/assets/{images => }/app_id_icon.svg | 0 angular-sample-spa/src/assets/{images => }/hint_icon.svg | 0 5 files changed, 5 insertions(+), 5 deletions(-) rename angular-sample-spa/src/assets/{images => }/20@2x.svg (100%) rename angular-sample-spa/src/assets/{images => }/app_id_icon.svg (100%) rename angular-sample-spa/src/assets/{images => }/hint_icon.svg (100%) diff --git a/angular-sample-spa/src/app/home/home.component.html b/angular-sample-spa/src/app/home/home.component.html index bd23086..84fc2f9 100644 --- a/angular-sample-spa/src/app/home/home.component.html +++ b/angular-sample-spa/src/app/home/home.component.html @@ -5,20 +5,20 @@
{{idToken}}
{{userData}}
-
hint image
+
hint image
Hint: To view your ID Token
and User Information, click
diff --git a/angular-sample-spa/src/app/welcome/welcome.component.html b/angular-sample-spa/src/app/welcome/welcome.component.html index c7da9e9..090d777 100644 --- a/angular-sample-spa/src/app/welcome/welcome.component.html +++ b/angular-sample-spa/src/app/welcome/welcome.component.html @@ -1,7 +1,7 @@
- App ID Logo + App ID Logo

Welcome to the
IBM Cloud App ID SPA SDK
@@ -13,7 +13,7 @@

{{errorMessage}}
-
hint image
+
hint image
Hint: To get started, click
the Login button above to reveal
diff --git a/angular-sample-spa/src/assets/images/20@2x.svg b/angular-sample-spa/src/assets/20@2x.svg similarity index 100% rename from angular-sample-spa/src/assets/images/20@2x.svg rename to angular-sample-spa/src/assets/20@2x.svg diff --git a/angular-sample-spa/src/assets/images/app_id_icon.svg b/angular-sample-spa/src/assets/app_id_icon.svg similarity index 100% rename from angular-sample-spa/src/assets/images/app_id_icon.svg rename to angular-sample-spa/src/assets/app_id_icon.svg diff --git a/angular-sample-spa/src/assets/images/hint_icon.svg b/angular-sample-spa/src/assets/hint_icon.svg similarity index 100% rename from angular-sample-spa/src/assets/images/hint_icon.svg rename to angular-sample-spa/src/assets/hint_icon.svg From 4bcfdf123afd92163a2a7d06a1313f3e36319630 Mon Sep 17 00:00:00 2001 From: Bernie Date: Thu, 30 Jan 2020 17:41:35 -0700 Subject: [PATCH 17/20] Changed styles --- angular-sample-spa/README.md | 2 +- angular-sample-spa/src/app/app.component.html | 3 +- angular-sample-spa/src/app/app.component.ts | 5 -- angular-sample-spa/src/app/app.module.ts | 2 - .../src/app/home/home.component.css | 70 ---------------- .../src/app/home/home.component.html | 27 +------ .../src/app/home/home.component.ts | 36 --------- .../src/app/navbar/navbar.component.css | 17 ---- .../src/app/navbar/navbar.component.html | 3 - .../src/app/navbar/navbar.component.spec.ts | 25 ------ .../src/app/navbar/navbar.component.ts | 15 ---- .../src/app/welcome/welcome.component.css | 34 +------- .../src/app/welcome/welcome.component.html | 19 ++--- .../src/app/welcome/welcome.component.ts | 15 +--- angular-sample-spa/src/assets/20@2x.svg | 11 --- angular-sample-spa/src/assets/hint_icon.svg | 42 ---------- angular-sample-spa/src/styles.css | 81 ++----------------- 17 files changed, 21 insertions(+), 386 deletions(-) delete mode 100644 angular-sample-spa/src/app/navbar/navbar.component.css delete mode 100644 angular-sample-spa/src/app/navbar/navbar.component.html delete mode 100644 angular-sample-spa/src/app/navbar/navbar.component.spec.ts delete mode 100644 angular-sample-spa/src/app/navbar/navbar.component.ts delete mode 100644 angular-sample-spa/src/assets/20@2x.svg delete mode 100644 angular-sample-spa/src/assets/hint_icon.svg diff --git a/angular-sample-spa/README.md b/angular-sample-spa/README.md index 1d05c7c..71bac88 100644 --- a/angular-sample-spa/README.md +++ b/angular-sample-spa/README.md @@ -1,4 +1,4 @@ -# IBM Cloud AppID Angular Sample App +# IBM Cloud App ID Angular Sample App The IBM Cloud App ID SDK can be used with Angular to create a secure single-page application. You will need an IBM Cloud App ID instance with a single-page application created. Use the client ID and discovery endpoint from your application credentials to initialize the App ID instance. diff --git a/angular-sample-spa/src/app/app.component.html b/angular-sample-spa/src/app/app.component.html index 96aeb73..8455906 100644 --- a/angular-sample-spa/src/app/app.component.html +++ b/angular-sample-spa/src/app/app.component.html @@ -1,3 +1,2 @@ - - + diff --git a/angular-sample-spa/src/app/app.component.ts b/angular-sample-spa/src/app/app.component.ts index d4d06a3..31d13b1 100644 --- a/angular-sample-spa/src/app/app.component.ts +++ b/angular-sample-spa/src/app/app.component.ts @@ -1,5 +1,4 @@ import { Component } from '@angular/core'; - @Component({ selector: 'app-root', templateUrl: './app.component.html', @@ -8,12 +7,8 @@ import { Component } from '@angular/core'; export class AppComponent { displayStateStatus = 'hide'; userNameStatus = ''; - idTokenStatus = ''; - userDataStatus = ''; onChangeState(value) { this.displayStateStatus = 'show'; this.userNameStatus = value.userName; - this.idTokenStatus = value.idToken; - this.userDataStatus = value.userData; } } diff --git a/angular-sample-spa/src/app/app.module.ts b/angular-sample-spa/src/app/app.module.ts index ae6ebce..0ed9629 100644 --- a/angular-sample-spa/src/app/app.module.ts +++ b/angular-sample-spa/src/app/app.module.ts @@ -3,14 +3,12 @@ import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { HomeComponent } from './home/home.component'; -import { NavbarComponent } from './navbar/navbar.component'; import { WelcomeComponent } from './welcome/welcome.component'; @NgModule({ declarations: [ AppComponent, HomeComponent, - NavbarComponent, WelcomeComponent ], imports: [ diff --git a/angular-sample-spa/src/app/home/home.component.css b/angular-sample-spa/src/app/home/home.component.css index 02ef13e..e69de29 100644 --- a/angular-sample-spa/src/app/home/home.component.css +++ b/angular-sample-spa/src/app/home/home.component.css @@ -1,70 +0,0 @@ -.collapsibleButton { - display: flex; - margin: 0 auto; - cursor: pointer; - padding: 15px; - width: 700px; - border: none; - outline: none; - font-size: 14px; - text-align: left; - padding: 15px; - font-family: 'IBMPlexSans-Medium', sans-serif; - box-shadow: 0px -1px 5px 0px rgba(0, 0, 0, 0.15); -} -@-moz-document url-prefix() { - .collapsibleButton { - font-family: 'IBM Plex Sans Medium', sans-serif; - } -} - -.collapsibleButtonClicked { - display: flex; - margin: 0 auto; - cursor: pointer; - padding: 15px; - margin-top: 10px; - width: 800px; - border: none; - outline: none; - font-size: 14px; - text-align: left; - padding: 15px; - font-family: 'IBMPlexSans-Medium', sans-serif; - box-shadow: 0px -1px 5px 0px rgba(0, 0, 0, 0.15); -} -@-moz-document url-prefix() { - .collapsibleButtonClicked { - font-family: 'IBM Plex Sans Medium', sans-serif; - } -} - -.active { - transform: rotate(180deg); - margin-right: 20px; -} -.expand { - transform: rotate(0deg); - margin-right: 20px; -} -.contentHidden { - display: none; -} - -.contentShown { - display: block; - overflow: hidden; - padding: 15px; - width: 770px; - margin: 0 auto; - margin-bottom: 20px; - font-family: 'IBMPlexSans-light', sans-serif; - font-size: 1vw; - word-break: break-all; - box-shadow: 0px -1px 5px 0px rgba(0, 0, 0, 0.15); -} -@-moz-document url-prefix() { - .contentShown { - font-family: 'IBM Plex Sans Light', sans-serif; - } -} diff --git a/angular-sample-spa/src/app/home/home.component.html b/angular-sample-spa/src/app/home/home.component.html index 84fc2f9..2789f31 100644 --- a/angular-sample-spa/src/app/home/home.component.html +++ b/angular-sample-spa/src/app/home/home.component.html @@ -1,29 +1,8 @@
-

{{userName}}

-

You've made your first authentication.

-
-
- -
{{idToken}}
-
-
- -
{{userData}}
-
-
-
hint image
-
- Hint: To view your ID Token
- and User Information, click
- on the arrows above. -
+ App ID Logo +

{{userName}}

+

You've made your first authentication.

diff --git a/angular-sample-spa/src/app/home/home.component.ts b/angular-sample-spa/src/app/home/home.component.ts index aaeac66..cab73aa 100644 --- a/angular-sample-spa/src/app/home/home.component.ts +++ b/angular-sample-spa/src/app/home/home.component.ts @@ -8,41 +8,5 @@ import { Component, Input} from '@angular/core'; export class HomeComponent { @Input() displayState: string; @Input() userName: string; - @Input() idToken: string; - @Input() userData: string; - tokenContentClass = 'contentHidden'; - tokenButtonClass = 'collapsibleButton'; - tokenImageClass = 'expand'; - infoContentClass = 'contentHidden'; - infoButtonClass = 'collapsibleButton'; - infoImageClass = 'expand'; - tokenState = true; - infoState = true; - onTokenClick() { - if (this.tokenState) { - this.tokenContentClass = 'contentShown'; - this.tokenButtonClass = 'collapsibleButtonClicked'; - this.tokenImageClass = 'active'; - this.tokenState = false; - } else { - this.tokenContentClass = 'contentHidden'; - this.tokenButtonClass = 'collapsibleButton'; - this.tokenImageClass = 'expand'; - this.tokenState = true; - } - } - onInfoClick() { - if (this.infoState) { - this.infoContentClass = 'contentShown'; - this.infoButtonClass = 'collapsibleButtonClicked'; - this.infoImageClass = 'active'; - this.infoState = false; - } else { - this.infoContentClass = 'contentHidden'; - this.infoButtonClass = 'collapsibleButton'; - this.infoImageClass = 'expand'; - this.infoState = true; - } - } } diff --git a/angular-sample-spa/src/app/navbar/navbar.component.css b/angular-sample-spa/src/app/navbar/navbar.component.css deleted file mode 100644 index a327fe3..0000000 --- a/angular-sample-spa/src/app/navbar/navbar.component.css +++ /dev/null @@ -1,17 +0,0 @@ -.wrapper { - display: block; - background-color: #EBF0F7; - font-family: 'IBMPlexSans-SemiBold', sans-serif; - margin-bottom: 8%; - width: 100%; - height: 40px; - font-size: 14px; - color: #000000; - padding: 10px; - line-height: 40px; -} -@-moz-document url-prefix() { - .wrapper { - font-family: 'IBM Plex Sans SemiBold', 'Helvetica Neue', Arial, sans-serif; - } -} diff --git a/angular-sample-spa/src/app/navbar/navbar.component.html b/angular-sample-spa/src/app/navbar/navbar.component.html deleted file mode 100644 index f3d213a..0000000 --- a/angular-sample-spa/src/app/navbar/navbar.component.html +++ /dev/null @@ -1,3 +0,0 @@ -
- IBM Cloud AppID SDK Sample SPA -
diff --git a/angular-sample-spa/src/app/navbar/navbar.component.spec.ts b/angular-sample-spa/src/app/navbar/navbar.component.spec.ts deleted file mode 100644 index 9032ad2..0000000 --- a/angular-sample-spa/src/app/navbar/navbar.component.spec.ts +++ /dev/null @@ -1,25 +0,0 @@ -import { async, ComponentFixture, TestBed } from '@angular/core/testing'; - -import { NavbarComponent } from './navbar.component'; - -describe('NavbarComponent', () => { - let component: NavbarComponent; - let fixture: ComponentFixture; - - beforeEach(async(() => { - TestBed.configureTestingModule({ - declarations: [ NavbarComponent ] - }) - .compileComponents(); - })); - - beforeEach(() => { - fixture = TestBed.createComponent(NavbarComponent); - component = fixture.componentInstance; - fixture.detectChanges(); - }); - - it('should create', () => { - expect(component).toBeTruthy(); - }); -}); diff --git a/angular-sample-spa/src/app/navbar/navbar.component.ts b/angular-sample-spa/src/app/navbar/navbar.component.ts deleted file mode 100644 index 8e29f4e..0000000 --- a/angular-sample-spa/src/app/navbar/navbar.component.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { Component, OnInit } from '@angular/core'; - -@Component({ - selector: 'app-navbar', - templateUrl: './navbar.component.html', - styleUrls: ['./navbar.component.css'] -}) -export class NavbarComponent implements OnInit { - - constructor() { } - - ngOnInit() { - } - -} diff --git a/angular-sample-spa/src/app/welcome/welcome.component.css b/angular-sample-spa/src/app/welcome/welcome.component.css index 32da851..b28b04f 100644 --- a/angular-sample-spa/src/app/welcome/welcome.component.css +++ b/angular-sample-spa/src/app/welcome/welcome.component.css @@ -1,35 +1,3 @@ -.logo-icon { - display: block; - width: 70px; - height: 70px; - margin: 0 auto; - margin-bottom: 20px; -} -#login { - font-family: 'IBMPlexSans-Medium', sans-serif; - font-size: 14px; - color: #FFFFFF; - letter-spacing: 0; - text-align: center; - background-color: #4178BE; - border: none; - padding: 10px 40px; - text-decoration: none; - cursor: pointer; - width: 158px; - height: 40px; - margin: 0 auto; - margin-top: 20px; -} -@-moz-document url-prefix() { - #login { - font-family: 'IBM Plex Sans Medium', 'Helvetica Neue', Arial, sans-serif; - } -} -#error { - padding-top: 20px; - font-size: 14px; - color: red; -} + diff --git a/angular-sample-spa/src/app/welcome/welcome.component.html b/angular-sample-spa/src/app/welcome/welcome.component.html index 090d777..fcc1638 100644 --- a/angular-sample-spa/src/app/welcome/welcome.component.html +++ b/angular-sample-spa/src/app/welcome/welcome.component.html @@ -2,22 +2,13 @@
App ID Logo -

- Welcome to the
- IBM Cloud App ID SPA SDK
- Sample App -

+

+ Welcome to the
+ IBM Cloud App ID SPA SDK
+ Sample App +

-
{{errorMessage}}
-
-
hint image
-
- Hint: To get started, click
- the Login button above to reveal
- the App ID login Pop-up window. -
-
diff --git a/angular-sample-spa/src/app/welcome/welcome.component.ts b/angular-sample-spa/src/app/welcome/welcome.component.ts index 862b5e4..36bf3e3 100644 --- a/angular-sample-spa/src/app/welcome/welcome.component.ts +++ b/angular-sample-spa/src/app/welcome/welcome.component.ts @@ -1,15 +1,12 @@ import { Component, Output, EventEmitter, OnInit } from '@angular/core'; import AppID from 'ibmcloud-appid-js'; - @Component({ selector: 'app-welcome', templateUrl: './welcome.component.html', styleUrls: ['./welcome.component.css'] }) - export class WelcomeComponent implements OnInit { style = 'show'; - spinner = 'hide'; buttonDisplay = 'show'; errorStyle = 'hide'; errorMessage = ''; @@ -18,8 +15,8 @@ export class WelcomeComponent implements OnInit { async ngOnInit() { try { await this.appid.init({ - clientId: '', - discoveryEndpoint: '' + clientId: '1b0e3658-fc1f-402e-843c-18402d4dbe58', + discoveryEndpoint: 'https://eu-gb.appid.test.cloud.ibm.com/oauth/v4/5b1eb5f1-34bd-41fd-b6dd-e257c188a4dd/.well-known/openid-configuration' }); } catch (e) { this.errorMessage = e.message; @@ -29,21 +26,15 @@ export class WelcomeComponent implements OnInit { async onLoginClick() { try { this.buttonDisplay = 'hide'; - this.spinner = 'show'; const tokens = await this.appid.signin(); - const userInfo = await this.appid.getUserInfo(tokens.accessToken); const decodeIDTokens = tokens.idTokenPayload; const userName = 'Hi ' + decodeIDTokens.name + ', Congratulations!'; - const idToken = JSON.stringify(decodeIDTokens); - const userData = JSON.stringify(userInfo); this.style = 'hide'; - this.changeState.emit({userName, idToken, userData}); + this.changeState.emit({userName}); } catch (e) { this.errorMessage = e.message; - this.spinner = 'hide'; this.errorStyle = 'show'; this.buttonDisplay = 'show'; - } } } diff --git a/angular-sample-spa/src/assets/20@2x.svg b/angular-sample-spa/src/assets/20@2x.svg deleted file mode 100644 index 7978fd9..0000000 --- a/angular-sample-spa/src/assets/20@2x.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - Actions / Navigation / chevron--down / 20@2x - Created with Sketch. - - - - - - \ No newline at end of file diff --git a/angular-sample-spa/src/assets/hint_icon.svg b/angular-sample-spa/src/assets/hint_icon.svg deleted file mode 100644 index 14d8a45..0000000 --- a/angular-sample-spa/src/assets/hint_icon.svg +++ /dev/null @@ -1,42 +0,0 @@ - - - - Group 5 Copy - Created with Sketch. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/angular-sample-spa/src/styles.css b/angular-sample-spa/src/styles.css index 0b404eb..586d2ed 100644 --- a/angular-sample-spa/src/styles.css +++ b/angular-sample-spa/src/styles.css @@ -1,74 +1,7 @@ -body { - margin: 0; - padding: 0; - max-width: 100%; - overflow-x: hidden; -} -.welcome-display { - display: block; - margin: 0 auto; - width: 30%; - height: auto; - font-family: 'IBMPlexSans-Light', sans-serif; - font-size: 1.5vw; - color: #152935; - letter-spacing: 0; - text-align: center; -} -@-moz-document url-prefix() { - .welcome-display { - font-family: 'IBM Plex Sans Light', 'Helvetica Neue', Arial, sans-serif; - } -} -.hintSection { - display: flex; - justify-content: center; - margin-top: 5%; - margin-bottom: 10%; -} -.flex-bottom { - font-family: 'IBMPlexSans-Medium', sans-serif; - font-size: 14px; - color: #42535C; - letter-spacing: 0; - line-height: 20px; - font-weight: normal; - flex: none; - margin-right: 5px; - margin-left: 5px; -} -@-moz-document url-prefix() { - .flex-bottom { - font-family: 'IBM Plex Sans Medium', sans-serif; - } -} -.hide { - display: none; -} - -.show { - display: block; -} - -.loader { - /* display: block; */ - margin: 0 auto; - border: 16px solid #f3f3f3; - border-radius: 50%; - border-top: 16px solid #EBF0F7; - border-bottom: 16px solid #EBF0F7; - width: 60px; - height: 60px; - -webkit-animation: spin 2s linear infinite; - animation: spin 2s linear infinite; - } - - @-webkit-keyframes spin { - 0% { -webkit-transform: rotate(0deg); } - 100% { -webkit-transform: rotate(360deg); } - } - - @keyframes spin { - 0% { transform: rotate(0deg); } - 100% { transform: rotate(360deg); } - } +body {margin: 0;padding: 0;max-width: 100%;overflow-x: hidden;} +.hide {display: none;} +.show {display: block;} +.welcome-display {display: block;font-family: 'IBMPlexSans-Light', sans-serif;font-size: 1.5vw;text-align: center;margin: 10% auto 0;} +.logo-icon {width: 70px;height: 70px;} +#login {font-family: 'IBMPlexSans-Medium', sans-serif;font-size: 14px;color: #FFFFFF;text-align: center;background-color: #4178BE;border: none;cursor: pointer;width: 158px;height: 40px;margin: 20px auto 0;} +#error {padding-top: 20px;font-size: 14px;color: red;} From 2b00bc342e61a5b162e907971422a3e060965bfd Mon Sep 17 00:00:00 2001 From: Bernie Date: Mon, 3 Feb 2020 04:00:41 -0700 Subject: [PATCH 18/20] Removed credentials --- angular-sample-spa/src/app/welcome/welcome.component.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/angular-sample-spa/src/app/welcome/welcome.component.ts b/angular-sample-spa/src/app/welcome/welcome.component.ts index 36bf3e3..58caa7c 100644 --- a/angular-sample-spa/src/app/welcome/welcome.component.ts +++ b/angular-sample-spa/src/app/welcome/welcome.component.ts @@ -15,8 +15,8 @@ export class WelcomeComponent implements OnInit { async ngOnInit() { try { await this.appid.init({ - clientId: '1b0e3658-fc1f-402e-843c-18402d4dbe58', - discoveryEndpoint: 'https://eu-gb.appid.test.cloud.ibm.com/oauth/v4/5b1eb5f1-34bd-41fd-b6dd-e257c188a4dd/.well-known/openid-configuration' + clientId: '', + discoveryEndpoint: '' }); } catch (e) { this.errorMessage = e.message; From 8adff2d3c2a0965663d32e17fdd92fb371b90f6f Mon Sep 17 00:00:00 2001 From: Bernie Date: Mon, 3 Feb 2020 12:16:39 -0700 Subject: [PATCH 19/20] modified README file --- angular-sample-spa/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/angular-sample-spa/README.md b/angular-sample-spa/README.md index 8a518fd..c186364 100644 --- a/angular-sample-spa/README.md +++ b/angular-sample-spa/README.md @@ -10,22 +10,22 @@ The IBM Cloud App ID SDK can be used with Angular to create a secure single-page ## To run locally -1 Clone the repository. +1. Clone the repository. ``` git clone https://github.com/ibm-cloud-security/appid-sample-code-snippets.git ``` -2 Navigate to the workspace folder of the application. +2. Navigate to the workspace folder of the application. ``` -cd angular-sample-app +cd angular-sample-spa ``` -3 Install dependencies for the application. +3. Install dependencies for the application. ``` npm install ``` -4 Start the development server. Navigate to http://localhost:4200 to access your application. +4. Start the development server. Navigate to http://localhost:4200 to access your application. ``` ng serve ``` -5 Make sure you register your redirect_uri (in this case http://localhost:4200/*) with App ID to ensure that only authorized clients are allowed to participate in the authorization workflow. This can be done on the App ID dashboard under the Manage Authentication tab in the Authentication Settings. Click [here](https://cloud.ibm.com/docs/services/appid?topic=appid-managing-idp#add-redirect-uri) for more details. +5. Make sure you register your redirect_uri (in this case http://localhost:4200/*) with App ID to ensure that only authorized clients are allowed to participate in the authorization workflow. This can be done on the App ID dashboard under the Manage Authentication tab in the Authentication Settings. Click [here](https://cloud.ibm.com/docs/services/appid?topic=appid-managing-idp#add-redirect-uri) for more details. Well done! You successfully integrated IBM Cloud App ID's SDK for SPA into an Angular application. From 8326e7b235e2680894f012138ecec51fcb830158 Mon Sep 17 00:00:00 2001 From: Bernie Date: Tue, 4 Feb 2020 08:58:13 -0700 Subject: [PATCH 20/20] modified README file --- react-sample-app/README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/react-sample-app/README.md b/react-sample-app/README.md index 3ab317d..b4ac29d 100644 --- a/react-sample-app/README.md +++ b/react-sample-app/README.md @@ -10,45 +10,45 @@ The IBM Cloud App ID SDK can be used with React to create a secure single-page a ## To run locally -1 Clone the repository. +1. Clone the repository. ``` git clone https://github.com/ibm-cloud-security/appid-sample-code-snippets.git ``` -2 Navigate to application workspace folder. +2. Navigate to application workspace folder. ``` cd react-sample-app ``` -3 Install dependencies for the application. +3. Install dependencies for the application. ``` npm install ``` -4 Start the development server. Navigate to http://localhost:3000 to access your application. +4. Start the development server. Navigate to http://localhost:3000 to access your application. ``` npm start ``` ## Detailed instructions on Creating your app -1 Set up a frontend build pipeline using create-react-app. Then move into the project directory. +1. Set up a frontend build pipeline using create-react-app. Then move into the project directory. ``` npx create-react-app my-app cd my-app ``` -2 Install the IBM Cloud AppID SDK. +2. Install the IBM Cloud AppID SDK. ``` npm install ibmcloud-appid-js ``` -3 In your code editor, in the src directory of the application, open the App.js file. Import App ID by adding the following code: +3. In your code editor, in the src directory of the application, open the App.js file. Import App ID by adding the following code: ``` import AppID from 'ibmcloud-appid-js'; ``` -4 In the main App() function, declare a new App ID instance with useMemo, which recomputes a memoized value when a dependency changes. +4. In the main App() function, declare a new App ID instance with useMemo, which recomputes a memoized value when a dependency changes. ``` const appID = React.useMemo(() => {     return new AppID() }, []); ``` -5 Initialize App ID and add error handling. Add your [client ID and discovery endpoint](https://cloud.ibm.com/docs/services/appid?topic=appid-single-page#create-spa-credentials) which can be found in the Applications tab of the App ID dashboard. +5. Initialize App ID and add error handling. Add your [client ID and discovery endpoint](https://cloud.ibm.com/docs/services/appid?topic=appid-single-page#create-spa-credentials) which can be found in the Applications tab of the App ID dashboard. ``` const [errorState, setErrorState] = React.useState(false); const [errorMessage, setErrorMessage] = React.useState(''); @@ -64,7 +64,7 @@ const [errorMessage, setErrorMessage] = React.useState('');     } })(); ``` -6 Create a login action that will execute when the login button is clicked. After a successful authentication, the welcomeDisplayState will be set to true and the userName will be set to the name returned in the App ID token. +6. Create a login action that will execute when the login button is clicked. After a successful authentication, the welcomeDisplayState will be set to true and the userName will be set to the name returned in the App ID token. ``` const [welcomeDisplayState, setWelcomeDisplayState] = React.useState(false); const [loginButtonDisplayState, setLoginButtonDisplayState] = React.useState(true); @@ -83,14 +83,14 @@ const loginAction = async () => {   } }; ``` -7 Add a welcome div, the login button that calls the login action, and an error div. +7. Add a welcome div, the login button that calls the login action, and an error div. ``` {welcomeDisplayState &&
Welcome {userName}! You are now authenticated.
} {loginButtonDisplayState &&  } {errorState &&
{errorMessage}
} ``` -8 Save all of the files. Your entire App.js file should look like this: +8. Save all of the files. Your entire App.js file should look like this: ``` import React from 'react'; import logo from './logo.svg'; @@ -150,10 +150,10 @@ function App() { } export default App; ``` -9 Open your terminal. Run the following command to access your app from http://localhost:3000. +9. Open your terminal. Run the following command to access your app from http://localhost:3000. ``` npm start ``` -10 Make sure you register your redirect_uri (in this case http://localhost:3000/*) with App ID to ensure that only authorized clients are allowed to participate in the authorization workflow. This can be done on the App ID dashboard under the Manage Authentication tab in the Authentication Settings. Click [here](https://cloud.ibm.com/docs/services/appid?topic=appid-managing-idp#add-redirect-uri) for more details. +10. Make sure you register your redirect_uri (in this case http://localhost:3000/*) with App ID to ensure that only authorized clients are allowed to participate in the authorization workflow. This can be done on the App ID dashboard under the Manage Authentication tab in the Authentication Settings. Click [here](https://cloud.ibm.com/docs/services/appid?topic=appid-managing-idp#add-redirect-uri) for more details. Well done! You successfully integrated IBM Cloud App ID's SDK for SPA into a React application.