Prechádzať zdrojové kódy

update sign in info

junggilpark 1 rok pred
rodič
commit
9945a81293

+ 9 - 5
appPackage/manifest.json

@@ -6,9 +6,9 @@
     "packageName": "com.microsoft.teams.extension",
     "developer": {
         "name": "Teams App, Inc.",
-        "websiteUrl": "https://www.example.com",
-        "privacyUrl": "https://www.example.com/privacy",
-        "termsOfUseUrl": "https://www.example.com/termsofuse"
+        "websiteUrl": "https://www.microsoft.com",
+        "privacyUrl": "https://www.microsoft.com/privacy",
+        "termsOfUseUrl": "https://www.microsoft.com/termsofuse"
     },
     "icons": {
         "color": "color.png",
@@ -16,7 +16,7 @@
     },
     "name": {
         "short": "share",
-        "full": "Full name for share"
+        "full": "share"
     },
     "description": {
         "short": "Short description of share",
@@ -42,5 +42,9 @@
     ],
     "validDomains": [
         "${{TAB_DOMAIN}}"
-    ]
+    ],
+    "webApplicationInfo" : {
+        "id" : "${{TEAMS_APP_ID}}",
+        "resource" : "api://${{TAB_DOMAIN}}/${{TEAMS_APP_ID}}"
+    }
 }

+ 3 - 2
env/.env.dev

@@ -10,6 +10,7 @@ AZURE_RESOURCE_GROUP_NAME=
 RESOURCE_SUFFIX=
 
 # Generated during provision, you can also add your own variables.
-TEAMS_APP_ID=
+TEAMS_APP_ID=0673c862-7edc-455d-9636-5559a0a8f2b9
 TAB_AZURE_STORAGE_RESOURCE_ID=
-TAB_ENDPOINT=
+TAB_ENDPOINT=https://localhost:53000
+TAB_DOMAIN=localhost:53000

+ 13 - 5
package-lock.json

@@ -10,7 +10,7 @@
             "dependencies": {
                 "@azure/communication-identity": "^1.3.1",
                 "@azure/identity": "^4.0.1",
-                "@azure/msal-node": "^2.6.6",
+                "@azure/msal-node": "^2.8.1",
                 "@microsoft/microsoft-graph-client": "^3.0.7",
                 "@microsoft/teams-js": "^2.21.0",
                 "archiver": "^7.0.1",
@@ -300,11 +300,11 @@
             }
         },
         "node_modules/@azure/msal-node": {
-            "version": "2.6.6",
-            "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.6.6.tgz",
-            "integrity": "sha512-j+1hW81ccglIYWukXufzRA4O71BCmpbmCO66ECDyE9FuPno6SjiR+K+mIk4tg6aQ7/UO2QA/EnRmT6YN0EF1Hw==",
+            "version": "2.8.1",
+            "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.8.1.tgz",
+            "integrity": "sha512-VcZZM+5VvCWRBTOF7SxMKaxrz+EXjntx2u5AQe7QE06e6FuPJElGBrImgNgCh5QmFaNCfVFO+3qNR7UoFD/Gfw==",
             "dependencies": {
-                "@azure/msal-common": "14.8.1",
+                "@azure/msal-common": "14.10.0",
                 "jsonwebtoken": "^9.0.0",
                 "uuid": "^8.3.0"
             },
@@ -312,6 +312,14 @@
                 "node": ">=16"
             }
         },
+        "node_modules/@azure/msal-node/node_modules/@azure/msal-common": {
+            "version": "14.10.0",
+            "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.10.0.tgz",
+            "integrity": "sha512-Zk6DPDz7e1wPgLoLgAp0349Yay9RvcjPM5We/ehuenDNsz/t9QEFI7tRoHpp/e47I4p20XE3FiDlhKwAo3utDA==",
+            "engines": {
+                "node": ">=0.8.0"
+            }
+        },
         "node_modules/@azure/msal-node/node_modules/uuid": {
             "version": "8.3.2",
             "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz",

+ 1 - 1
package.json

@@ -8,7 +8,7 @@
     "dependencies": {
         "@azure/communication-identity": "^1.3.1",
         "@azure/identity": "^4.0.1",
-        "@azure/msal-node": "^2.6.6",
+        "@azure/msal-node": "^2.8.1",
         "@microsoft/microsoft-graph-client": "^3.0.7",
         "@microsoft/teams-js": "^2.21.0",
         "archiver": "^7.0.1",

+ 126 - 62
src/app.js

@@ -10,32 +10,35 @@ const {getFetch, updateFetch} = require('./fetch');
 const bodyParser = require('body-parser');
 const https = require('https');
 const JSZIP = require('jszip');
-require('dotenv').config({ path: './env/.env.test' });
+require('dotenv').config({ path: './env/.env.local' });
 const session = require('express-session');
 const multer  = require('multer');
 const XLSX = require('xlsx');
 const pptxgen = require('pptxgenjs');
+const msal = require('@azure/msal-node');
+
+require('dotenv').config({ path: './env/.env.test' });
+
+const msalConfig = {
+  auth: {
+      clientId: process.env.TEAMS_APP_ID,
+      authority: "https://login.microsoftonline.com/"+process.env.TEAMS_APP_TENANT_ID,
+      clientSecret: process.env.TEAMS_APP_SECRET,
+      knownAuthorities: [],
+  },
+  cache: {
+      // your implementation of caching
+  },
+  system: {
+      loggerOptions: { /** logging related options */ }
+  }
+} 
+
+const cca = new msal.ConfidentialClientApplication(msalConfig);
 
 const {Document, Packer, Paragraph, TextRun} = require('docx');
 let WebSocketServer = require('websocket').server;
 const redirectUri = 'https://localhost:53000/redirect';
-// const {DeviceCodeCredential} = require('@azure/identity');
-// const {TokenCredentialAuthenticationProvider} = require('@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials')
-// const {Client} = require('@microsoft/microsoft-graph-client')
-
-// const credential = new DeviceCodeCredential({
-//   tenantId : process.env.TENANT_ID,
-//   clientId : process.env.CLIENT_ID,
-//   userPromptCallback: (info) => {
-//     console.log(info.message);
-//   },
-// });
-
-// const authPr = new TokenCredentialAuthenticationProvider(credential, {
-//   scopes: ['.default'],
-// });
-
-// const graphClient = Client.initWithMiddleware({ authProvider: authPr });
 
 const storage =  multer.diskStorage({
   destination: function (req, file, cb) { 
@@ -49,15 +52,7 @@ const upload = multer(storage);
 
 const serverApp = express();
 const endPoint = process.env.GRAPH_API_ENDPOINT + 'v1.0';
-Buffer.prototype.toArrayInteger = function(){
-  if (this.length > 0) {
-      const data = new Array(this.length);
-      for (let i = 0; i < this.length; i=i+1)
-          data[i] = this[i];
-      return data;
-  }
-  return [];
-}
+
 serverApp.use(session({
   secret: process.env.EXPRESS_SESSION_SECRET,
   resave: false,
@@ -135,14 +130,25 @@ server.listen(SERVER_PORT, function () {
 });
 
 serverApp.get("/tab", 
-  isAuthenticated, 
+  // isAuthenticated, 
   async function (req, res, next) {
     res.sendFile(path.join(__dirname, "/views/hello.html"), 
       // { idTokenClaims: req.session.account.idTokenClaims }
     );
   }
 );
-
+serverApp.post("/getProfileOnBehalfOf", async (req, res, next) => {
+  result = await cca.acquireTokenOnBehalfOf({
+    oboAssertion: req.body.token,
+    scopes: [".default"]
+  });
+  req.session.tokenCache = result.tokenCache;
+  req.session.accessToken = result.accessToken;
+  req.session.idToken = result.idToken;
+  req.session.account = result.account;
+  req.session.auth = result;
+  return res.send(result);
+})
 function isAuthenticated(req, res, next) {
   if (!req.session.isAuthenticated) {
     return res.redirect('/auth/signin'); // redirect to sign-in route
@@ -170,8 +176,8 @@ serverApp.get("/auth/signin", authProvider.login({
 serverApp.post("/redirect", authProvider.handleRedirect());
 
 serverApp.post("/api-get",   
-  isAuthenticated,
-  isAccessToken, 
+  // isAuthenticated,
+  // isAccessToken, 
   async (req, res, next) => {
     const uri = req.body.api_uri || req.session.apiUri;
     let param = {};
@@ -231,11 +237,69 @@ serverApp.post("/api-post", authProvider.acquireToken({
   successRedirect: '/post-redirect'
 }));
 
-serverApp.post("/getGroupList", authProvider.acquireToken({
-    scopes: ['.default'],
-    redirectUri: redirectUri,
-    successRedirect: '/group-redirect'
-}));
+// serverApp.post("/getGroupList", authProvider.acquireToken({
+//     scopes: ['.default'],
+//     redirectUri: redirectUri,
+//     successRedirect: '/group-redirect'
+// }));
+serverApp.post("/getGroupList",  async function (req, res, next) {
+  try {
+      const oneDrive = await getFetch(endPoint + "/me/drive/root", req.session.accessToken);
+      const sharePointIds = await getFetch(endPoint + "/me/drive/SharePointIds", req.session.accessToken);
+      // const publicTeam = await getFetch(endPoint + "/groups?$filter=groupTypes/any(c:c+eq+'Unified')", req.session.accessToken);
+      const graphResponse = await getFetch(endPoint + "/me/joinedTeams", req.session.accessToken);
+      const sites = await getFetch(endPoint + "/sites/root", req.session.accessToken);
+      const sitesSharePoint = await getFetch(endPoint + "/sites/root/SharePointIds", req.session.accessToken);
+
+      // const public = publicTeam.value;
+      const teams = graphResponse.value;
+      oneDrive.sharePoint = sharePointIds;
+      sites.sharePoint = sitesSharePoint;
+      const resultObj = {
+        oneDrive : {
+          teams: oneDrive,
+        },
+        joinedTeams : {
+          teams : teams,
+          // teams : public,
+          items : {},
+        },
+        sites : {
+          teams : sites,
+        },
+      }
+
+      if (teams && teams.length) {
+      // if (public && public.length) {
+        // const options = {
+        //   responseType: 'arraybuffer',
+        //   headers: {
+        //     Authorization: `Bearer ${req.session.accessToken}`,
+        //     ConsistencyLevel: 'eventual',
+        //     withCredentials:true,
+        //   },
+        // };
+        for (let team of teams) {
+        // for (let team of public) {
+          const item = await getFetch(endPoint + "/groups/"+team.id+"/drive/items/root/children", req.session.accessToken);
+          const sharePoint = await getFetch(endPoint + "/groups/"+team.id+"/drive/SharePointIds", req.session.accessToken);
+          // const image = await axios.get(endPoint + "/groups/" + team.id + "/photo/$value", options);
+          // if (image && image.data) {
+          //   team.image = image.data;
+          // }
+          if (sharePoint) {
+            team.sharePoint = sharePoint;
+          }
+          if (item && item.value) {
+            resultObj.joinedTeams.items[team.id] = item.value;
+          }
+        }
+      }
+      res.json(resultObj);
+  } catch (error) {
+      next(error);
+  } 
+});
   
 
 serverApp.get("/group-redirect", 
@@ -313,8 +377,8 @@ function isAccessTokens(req, res, next) {
 }
 
 serverApp.post('/api/makeFolder', 
-    isAuthenticated,
-    isAccessTokens,
+    // isAuthenticated,
+    // isAccessTokens,
     async (req, res, next)=>{
 
       const options = {
@@ -372,8 +436,8 @@ function getErrorMessage(error) {
 }
 
 serverApp.post('/api/makeWord', 
-    isAuthenticated,
-    isAccessTokens,
+    // isAuthenticated,
+    // isAccessTokens,
     async (req, res, next)=>{
       const options = {
         headers: {
@@ -422,8 +486,8 @@ serverApp.post('/api/makeWord',
 })
 
 serverApp.post('/api/makeExcel', 
-    isAuthenticated,
-    isAccessTokens,
+    // isAuthenticated,
+    // isAccessTokens,
     async (req, res, next)=>{
 
       const fileOptions = { headers: {
@@ -458,8 +522,8 @@ serverApp.post('/api/makeExcel',
 })
 
 serverApp.post('/api/makePptx', 
-    isAuthenticated,
-    isAccessTokens,
+    // isAuthenticated,
+    // isAccessTokens,
     async (req, res, next)=>{
 
       const options = { headers: {
@@ -491,8 +555,8 @@ serverApp.post('/api/makePptx',
 })
 
 serverApp.post('/api/check-name', 
-    isAuthenticated,
-    isAccessTokens,
+    // isAuthenticated,
+    // isAccessTokens,
     async (req, res, next)=>{
 
       const options = {
@@ -671,8 +735,8 @@ serverApp.post('/api/check-name',
 // });
 
 serverApp.post('/api/upload', upload.array('file'),
-  isAuthenticated,
-  isAccessTokens,
+  // isAuthenticated,
+  // isAccessTokens,
   async (req, res, next)=>{
     const startTime = new Date();
     const files = req.files;
@@ -838,8 +902,8 @@ serverApp.post('/api/upload', upload.array('file'),
 
 
 serverApp.post('/api/download',
-  isAuthenticated,
-  isAccessTokens,
+  // isAuthenticated,
+  // isAccessTokens,
   async (req, res, next)=>{
     if (req.body) {
       const {siteId, path, fileIds, zipName} = req.body;
@@ -1002,8 +1066,8 @@ async function getFolderItems(url, array, options) {
 }
 
 serverApp.post('/api/delete', 
-  isAuthenticated,
-  isAccessTokens,
+  // isAuthenticated,
+  // isAccessTokens,
   async (req, res, next)=>{
     if (req.body) {
       const {siteId, itemIds} = req.body;
@@ -1045,8 +1109,8 @@ serverApp.post('/api/delete',
   })
 
 serverApp.post('/api/update-name', 
-  isAuthenticated,
-  isAccessTokens,
+  // isAuthenticated,
+  // isAccessTokens,
   async (req, res, next)=>{
     if (req.body) {
       const {siteId, itemId, name} = req.body;
@@ -1080,8 +1144,8 @@ serverApp.post('/api/update-name',
   });
   
 serverApp.post('/api/move-item', 
-  isAuthenticated,
-  isAccessTokens,
+  // isAuthenticated,
+  // isAccessTokens,
   async (req, res, next)=>{
     if (req.body) {
       const {id, name, siteId, text} = req.body;
@@ -1128,8 +1192,8 @@ serverApp.post('/api/move-item',
 });
   
 serverApp.post('/api/copy-item', 
-isAuthenticated,
-isAccessTokens,
+// isAuthenticated,
+// isAccessTokens,
 async (req, res, next)=>{
   if (req.body) {
     const {id, name, siteId, driveId, text} = req.body;
@@ -1201,8 +1265,8 @@ serverApp.post('/api/loading',
 
 
 serverApp.post('/api/folder-count',
-  isAuthenticated,
-  isAccessTokens,
+  // isAuthenticated,
+  // isAccessTokens,
   async (req, res, next)=>{
     if (req.body) {
       const {id, siteId, originSiteId, originId, name, totalCount} = req.body;
@@ -1270,8 +1334,8 @@ async function getFolderItemsCount(siteId, id, options, count) {
 
 
 serverApp.post('/api/add-tab', 
-isAuthenticated,
-isAccessTokens,
+// isAuthenticated,
+// isAccessTokens,
 async (req, res, next)=>{
   if (req.body) {
     const {name, siteId, path, teamId, teamName, bindId} = req.body;

+ 1 - 0
src/auth/AuthProvider.js

@@ -221,6 +221,7 @@ class AuthProvider {
             };
             
             try {
+                console.log('==============================================리다이렉트================================================================')
                 const authCodeUrlResponse = await msalInstance.getAuthCodeUrl(req.session.authCodeUrlRequest);
 
                 res.redirect(authCodeUrlResponse);

+ 1 - 0
src/static/scripts/teamsapp.js

@@ -4,6 +4,7 @@
   // Call the initialize API first
   microsoftTeams.app.initialize().then(function () {
     microsoftTeams.app.getContext().then(function (context) {
+      console.log(context);
       if (context?.app?.host?.name) {
         updateHubState(context.app.host.name);
       }

+ 88 - 17
src/views/hello.html

@@ -4,13 +4,13 @@
     <meta name="viewport" content="width=device-width, initial-scale=1.0" />
     <link rel="icon" href="/favicon.ico" />
     <link rel="stylesheet" type="text/css" href="/static/styles/custom.css?v=06" />
-    <!-- <script
+    <script
       src="https://res.cdn.office.net/teams-js/2.17.0/js/MicrosoftTeams.min.js"
       integrity="sha384-xp55t/129OsN192JZYLP0rGhzjCF9aYtjY0LVtXvolkDrBe4Jchylp56NrUYJ4S2"
       crossorigin="anonymous"
     ></script>
-    <script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.2.1/js/msal.js"></script>
-    <script src="/static/scripts/teamsapp.js"></script> -->
+    <!-- <script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.2.1/js/msal.js"></script> -->
+    <script src="/static/scripts/teamsapp.js"></script>
     <script src="https://code.jquery.com/jquery-latest.min.js"></script>
     <title>Microsoft Teams Tab</title>
     <style>
@@ -87,8 +87,79 @@
   });
 
   $(()=>{
-    // microsoftTeams.appInitialization.notifySuccess();
-    getGroupList();
+    // console.log();
+    // console.log();
+    // microsoftTeams.app.getContext().then((result)=>{
+    //   console.log(result);
+    // })
+    // .catch((error)=>{
+    //   console.log(error);
+    // })
+    // 
+    microsoftTeams.app.initialize().then(() => {
+      microsoftTeams.appInitialization.notifySuccess();  
+      getClientSideToken()
+            .then((clientSideToken) => {
+              // console.log(clientSideToken);
+                return getServerSideToken(clientSideToken);
+            })
+            .then((profile) => {
+              // console.log(profile);
+              getGroupList();
+                // return useServerSideToken(profile);
+            })
+            .catch((error) => {
+              console.log(error);
+            })
+    })
+
+    function getClientSideToken() {
+
+        return new Promise((resolve, reject) => {
+            microsoftTeams.authentication.getAuthToken().then((result) => {
+                resolve(result);
+            }).catch((error) => {
+                reject("Error getting token: " + error);
+            });
+        });
+    }
+
+    function getServerSideToken(clientSideToken) {
+        return new Promise((resolve, reject) => {
+            microsoftTeams.app.getContext().then((context) => {
+                fetch('/getProfileOnBehalfOf', {
+                    method: 'post',
+                    headers: {
+                        'Content-Type': 'application/json'
+                    },
+                    body: JSON.stringify({
+                        'tid': context.user.tenant.id,
+                        'token': clientSideToken
+                    }),
+                    mode: 'cors',
+                    cache: 'default'
+                })
+                .then((response) => {
+                    if (response.ok) {
+                        return response.json();
+                    } else {
+                        reject(response.error);
+                    }
+                })
+                .then((responseJson) => {
+                    if (responseJson.error) {
+                        reject(responseJson.error);
+                    } else {
+                        const profile = responseJson;
+
+                        resolve(profile);
+                    }
+                });
+            });
+        });
+    }
+    
+    // getGroupList();
     window.oncontextmenu = function () {
         return false;
     };
@@ -418,18 +489,18 @@
     }
 
     function openWebUrl(url, name, event) {
-      //window.open(url);
-      $.ajax({
-        method: 'get', 
-        url : url, 
-        type : 'json',
-        success : (res)=>{
-          console.log(res);
-        },
-        error : (error)=>{
-          console.log(error);
-        }
-      })
+      window.open(url);
+      // $.ajax({
+      //   method: 'get', 
+      //   url : url, 
+      //   type : 'json',
+      //   success : (res)=>{
+      //     console.log(res);
+      //   },
+      //   error : (error)=>{
+      //     console.log(error);
+      //   }
+      // })
     }
 
     function addTabs(bindId) {